python numpy tolist()添加了多少开销?

时间:2016-09-16 03:09:37

标签: python c++ arrays numpy wrapper

我正在使用一个python程序,它使用numpy数组作为数组的标准数据类型。对于繁重的计算,我将数组传递给C ++库。为此,我使用pybind。但是,我需要使用python 2016-09-10。我通过以下方式从list数组和numpy进行转换:

list

此转换产生多少开销?我希望它不会创建一个全新的副本。 Numpy参考说:

  

ndarray.tolist()

     

将数组数据的副本作为(嵌套)Python列表返回。数据项   被转换为最接近的兼容Python类型。

2 个答案:

答案 0 :(得分:3)

很多。对于简单的内置类型,您可以在对象上使用sys.getsizeof来确定与该对象关联的内存开销(对于容器,这不包括存储在其中的值,只包括用于存储它们的指针)。

因此,例如,list 100个小int s(但大于256以避免小int缓存)(在我的3.5.1 Windows x64安装上):< / p>

>>> sys.getsizeof([0] * 100) + sys.getsizeof(0) * 100
3264

或大约需要3 KB的内存。如果这些相同的值存储在numpy array int32中,每个数字没有Python对象,并且没有每个对象指针,则大小将降至大约100 * 4(加上另外几十个字节,对于array对象开销本身而言,在500字节以下。对于每个额外的小int,增量成本为24字节(尽管如果它在小型int缓存中为-5到256 IIRC的值,它是免费的),以及8字节对于list中的存储,总共32个字节,而C级类型为4,大约是存储要求的8倍(并且您仍然存储原始对象)。

如果你有足够的内存来处理它,那就这样吧。但除此之外,您可能会尝试查看一个包装,它允许您传递缓冲区协议支持对象(Py3上的numpy.arrayarray.array,通过内存视图切片分配填充的ctypes数组等。)所以不需要转换为Python级别类型。

答案 1 :(得分:3)

是的,它将是新副本。数组的数据布局与列表的数据布局非常不同。

数组具有形状和步幅等属性,以及包含元素的1d数据缓冲区 - 只是一组连续的字节。它是将其视为浮点数,整数,字符串,1d,2d等的其他属性和代码。

列表是指针的缓冲区,每个指针指向内存中的对象。它可能指向数字,字符串或其他列表。它不会指向数组的数据缓冲区或其中的元素。

有连接的numpy数组与编译代码和使用数组数据缓冲区的C数组。 cython是常见问题。关于numpy的C API还有一个完整的文档部分。我对pbind了解一切。如果它需要一个列表界面,它可能不是最好的。

当我使用timeit进行tolist()测试时,它看起来并不那么昂贵。

=======================

但是看pybind11 github,我发现了numpy的一些引用,这个

http://pybind11.readthedocs.io/en/latest/advanced.html#numpy-support

文档页面。它支持缓冲协议和numpy数组。因此,您不必经历tolist步骤。

#include <pybind11/numpy.h>
void f(py::array_t<double> array);