Ale*_*ach 5 c++ python numpy boost-python python-c-extension
我最近开始使用Boost的Python库来包装一个相当大的C++库的一部分.
很偶然,我发现Boost Python创建的每个Python对象至少比Python List的大小要大.
使用noddy_NoddyType
例如从C-Python的API文档,我可以很容易地露出新对象类型实例,noddy_NoddyObject
.
使用原始C-Python API,这与自定义Python对象一样小而简单: -
>>> import noddy, sys
>>> print sys.getsizeof( noddy.Noddy ) # PyTypeObject size?
872
>>> print sys.getsizeof( noddy.Noddy() ) # PyObject size
16
Run Code Online (Sandbox Code Playgroud)
并与基础对象进行比较: -
>>> print sys.getsizeof( object )
872
>>> print sys.getsizeof( object() )
16
Run Code Online (Sandbox Code Playgroud)
这是预期的,但是当我noddy_NoddyObject
使用Boost Python 公开时呢?
>>> print sys.getsizeof( noddy.Noddy )
904
>>> print sys.getsizeof( noddy.Noddy() )
80
Run Code Online (Sandbox Code Playgroud)
说什么?!!那不太理想......对象实例比它们需要的大5倍!
(这在非64位计算机上会有所不同.)
在Boost Python维基上,有一些额外膨胀的解释: -
内存消耗
通常,带有相应Python对象的包装C++对象的大小为:
- 一个新式的类(派生自Python中的'object')实例加
- 所需的额外尺寸,以允许在该实例的可变长度数据,加
- 加上C++对象的大小
vtable指针的大小,加上指向C++对象的实例持有者的指针- 需要零个或多个填充字节以确保实例持有者正确对齐.
你可以看到这个
boost/python/object/instance.hpp
.instance<value_holder<T> >
对于某些C++类,大多数Python对象都表示为T
.
但是,没有迹象表明如何减少实例大小,也没有如何使用自定义PyTypeObject
.
所以,instance.hpp
你可以看到,所有boost::python::instance
的使用PyObject_VAR_HEAD
在其基类的声明.这可以解释的更接近的相似性在加速的大小Python的编译noddy_NoddyObject
,到一个Python的list
,或者numpy.array
: -
>>> print sys.getsizeof( list )
872
>>> print sys.getsizeof( list() )
72
>>> print sys.getsizeof( numpy.array )
72
>>> print sys.getsizeof( numpy.array() )
80
Run Code Online (Sandbox Code Playgroud)
(哦,这很有趣..如果我没弄错的话,numpy.array
是一个最小PyObject
实例的大小,它比a小得多PyTypeObject
.我想知道那里有什么含义......)
除了对象大小之外,我在这里引起的关注是堆事务.我有一个C++基类,它几乎只包含与内存管理相关的功能:它有new
和delete
运算符; 大量与引用计数相关的方法,并由大约一百个其他C++类继承.
曾经阅读过关于定义新类型的C-Python API文档,我认为这里有一种新类型.通过定义一个新PyTypeObject
结构,并将其成员(tp_alloc
等)指向C++类的运算符和成员函数,我想我可以让Python解释器直接调用C++成员函数.然后,派生类类型在典型boost::python::object
实例和(已经管理的)C++类之间没有重复的功能.
使用bp::class_<>
模板,我认为C++代码和Python代码将分别管理内存到类实例,这看起来可能非常低效.
PyTypeObject
通过使用新的PyTypeObject
,我认为我的所有问题都将得到解决.简单对象的内存占用量可能要小得多(如果我可以noddy_NoddyObject
降到24个字节,我会非常高兴)并且似乎可以更灵活地管理内存.
那么,有没有其他人觉得有必要定义一个新的PyTypeObject
,不同的Boost Python实例的默认值?怎么会这样呢?
通过采用更大的基础类型,似乎Boost正在失去效率和灵活性.减肥总是比获得更多更痛苦.
归档时间: |
|
查看次数: |
528 次 |
最近记录: |