优化boost :: python :: object实例

时间:2013-04-19 21:29:45

标签: c++ python numpy boost-python python-c-extension

我最近开始使用Boost's Python库来包装相当大的C ++库的部分内容。

很偶然,我发现Boost Python创建的每个Python对象至少都比Python List的大小大。

简单类型

使用noddy_NoddyType example中的C-Python API docs,我可以非常轻松地公开新的对象类型实例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

与基础对象进行比较: -

>>> print sys.getsizeof( object )
872
>>> print sys.getsizeof( object() )
16

这是预期的,但是当我使用Boost Python公开noddy_NoddyObject时呢?

>>> print sys.getsizeof( noddy.Noddy )
904
>>> print sys.getsizeof( noddy.Noddy() )
80

说什么?!!那不太理想......对象实例比它们需要的大5倍!

(这在非64位计算机上会有所不同。)

在Boost Python维基上,有额外膨胀的some explanation: -

  

内存消耗

     

通常,带有相应Python对象的包装C ++对象是   大小:

     
      
  • 一个新式的类(派生自Python中的'object')   实例加上
  •   
  • 允许可变长度数据所需的额外大小   在实例中,加上
  •   
  • C ++对象的大小,加上
  •   
  • vtable指针的大小,加上指向C ++对象的指针   instanceholder,加上
  •   
  • 确保需要零个或多个填充字节   实例持有者正确对齐。
  •   
     

您可以在boost/python/object/instance.hpp中看到这一点。对于某些C ++类instance<value_holder<T> >,大多数Python对象由T表示。

但是,显然没有迹象表明如何减少实例大小,以及如何使用自定义PyTypeObject

序列类型

因此,在instance.hpp中,您可以看到所有boost::python::instance在其基类声明中使用PyObject_VAR_HEAD。这可以解释Boost Python编译的noddy_NoddyObject的大小与Python listnumpy.array的大小更接近的相似性: -

>>> print sys.getsizeof( list )
872
>>> print sys.getsizeof( list() )
72
>>> print sys.getsizeof( numpy.array )
72
>>> print sys.getsizeof( numpy.array() )
80

(哦,这很有意思......如果我没弄错的话,numpy.array是最小PyObject实例的大小,它比PyTypeObject小得多。我想知道是什么其中的含义是..)

内存管理

除了对象大小之外,我在这里引起的关注是堆事务。我有一个C ++基类,它几乎只包含与内存管理相关的功能:它有newdelete运算符;大量与引用计数相关的方法,并且由大约一百个其他C ++类继承。

曾经读过C-Python API docs on Defining new Types,我觉得这里有一种新的类型。通过定义一个新的PyTypeObject结构,并将其成员(tp_alloc等)指向C ++类的运算符和成员函数,我想我可以让Python解释器直接调用C ++成员函数。派生类类型在典型的boost::python::object实例和(已经管理的)C ++类之间没有重复的功能。

使用bp::class_<>模板,我认为C ++代码和Python代码将分别管理内存到类实例,这看起来可能非常低效。

制作新的PyTypeObject

通过使用新的PyTypeObject,我认为我的所有问题都将得到解决。简单对象的内存占用量可能要小得多(如果我可以将noddy_NoddyObject降低到24个字节,我会非常高兴)并且似乎可以更灵活地管理内存。

那么,还有其他人觉得有必要定义一个新的PyTypeObject,不同于Boost Python实例的默认值吗?怎么会这样呢?

通过采用更大的基础类型,似乎Boost正在失去效率和灵活性。减肥总是比获得更多更痛苦。

0 个答案:

没有答案