由于使用了对象类型声明,这种扩展类型在多大程度上可能效率低下?

时间:2017-01-28 02:56:09

标签: python cython

由于需要使用DefaultDict的Python对象类型声明,我被告知以下扩展类型may not be very efficient。有人可以解释为什么会这样,以及dict是否值得使用(而不是cdef class CythonClass(object): cdef int var1, var2 cdef object defaultdict def __init__(self, a, b): self.var1 = a self.var2 = b self.defaultdict = DefaultDict(DefaultDict([])) )?

{{1}}

1 个答案:

答案 0 :(得分:1)

我可能夸大了my other answer中的效率部分。我的意思是:当你不得不使用Python对象时,不要期望巨大的加速(超过1.5-2x)。

你可以使用它们,它不会比在python代码中使用它们慢(除非极少数情况)。然而,使用Cython的强大功能是你可以利用本机c类型和同类数据结构,比如c-arrays(它可以比python列表甚至词典快得多),或者如果你去c ++那么vector,{{ 1}}等等。

在处理Python对象时要记住的一点是所有 python对象都是指向某些结构的指针,因此每个对象都添加了一层间接 - 这对于Python unordered_map来说甚至是正确的。然而,Cython int是没有该间接的C整数。这是Cython中int - 循环更快的主要原因之一。 (但它们限制在64位范围内,而不是像Python中那样无限制,这是权衡)。

另一点是操作python对象意味着你需要经历pythons查找,pythons操作等。但是对于内置对象,cython可以使用Python C API来获取通过避免基于python的查找来增加速度(我想,for不在其中),例如使用声明的dicts,下面的代码编译方式不同:

DefaultDict

你可能猜到哪一个更快,直接地对dict进行处理的那个(def dumb_func(dict dct, str key): return dct[key] # translates to: __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_v_key) def dumb_func(object dct, object key): # different signature return dct[key] # translates to: PyObject_GetItem(__pyx_v_dct, __pyx_v_key) 可能是PyDict_GetItemPyDict_GetItemString的复杂包装器,或者只是一个带有__Pyx_PyDict_GetItem的python对象(通过python查找)。这不会是一个巨大的加速,但它是显而易见的。

最后我会说正常(和声明的)PyObject_GetItem在Cython代码中肯定比dict(除了某些C或C ++类)更快。