由于需要使用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}}
答案 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_GetItem
和PyDict_GetItemString
的复杂包装器,或者只是一个带有__Pyx_PyDict_GetItem
的python对象(通过python查找)。这不会是一个巨大的加速,但它是显而易见的。
最后我会说正常(和声明的)PyObject_GetItem
在Cython代码中肯定比dict
(除了某些C或C ++类)更快。