2016-09-16 26 views
0

我使用的是使用numpy数组作为数组的标准数据类型的python程序。对于繁重的计算,我将数组传递给C++库。为了这样做,我使用pybind。不过,我需要使用python list。我从numpy阵列进行转换,并通过listpython numpy tolist()添加了多少开销?

NativeSolver.vector_add(array1.tolist(), array2.tolist(), ...) 

多少开销,这是否转换生成?我希望它不会创建一个全新的副本。 numpy的参考表示:

ndarray.tolist()

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

+0

我在'pybind' github和文档中发现了缓冲区协议和numpy的引用。 – hpaulj

回答

3

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

因此,例如,一个list 100的短小int S(但大于256,以避免小int缓存)是(在我的Windows 3.5.1安装64位)的

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

或约3 KB需要内存。如果那些相同的值被存储在numpyarrayint32的S,每个号码的Python对象,并且没有每个对象的指针,该尺寸将下降到大约100 * 4(加另一个几十个字节,对于array对象开销本身) ,500字节以下的地方。对于每个附加小型文件int的增量成本为24个字节(尽管它对于-5到256 IIRC中的值在小型整型高速缓存中是空闲的),对于list中的存储空间为8个字节,总共32字节,对于。对于C级别类型,大约是存储要求的8倍(并且您仍然在存储原始对象)。

如果你有足够的内存来处理它,那就这样吧。但除此之外,你可能想寻找一个包裹,让您在缓冲协议支持对象传递(numpy.arrayarray.array上PY3,通过memoryview片分配等填充​​阵列)不需要那么转换到Python级别类型。

3

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

数组具有形状和进展,和包含的元素的一维数据缓冲器属性 - 只是一组连续的字节。它的其他属性和代码将它们视为浮标,整型,字符串,1D,2D等

列表是指针的缓冲器,每个指针指向对象别的地方在存储器中。它可能指向一个数字,一个字符串或另一个列表。它不会指向数组的数据库或元素。

有接口与编译的代码和C数组numpy的阵列,使使用数组数据缓冲液中。 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); 
+0

我知道这件事。我不想放弃某些pybind11数据类型的STL数据类型。我现在用SWIG结束了。在我看来,SWIG是唯一允许python和C++文件尽可能保持不变的包装。 –