python – 为什么__setitem__比cdef-classes的等效“普通”方法
看起来,对于Cython的cdef类,使用类特殊方法有时比相同的“常规”方法更快,例如__setitem__比setitem快3倍:
现在:
这既不是Python的“正常”行为,特殊功能甚至更慢(并且比Cython等效的速度慢):
在Cython中,所有特殊功能都不是这样的:
这导致:
即几乎相同的运行时间. 为什么__setitem __(…)比cdef-class中的setitem(…)快得多,即使两者都是cython化的? 最佳答案
通用Python方法调用有相当多的开销 – Python查找相关属性(字典查找),确保属性是可调用对象,并且一旦调用它就处理结果.此开销也适用于cdef类的通用def函数(唯一的区别是该方法的实现在C中定义).
但是,可以优化C/C++ython类的特殊方法,如下所示: 查找速度 作为捷径, 对于cdef类,Cython似乎只生成第一个(通用)类,因此加速不是直接传递C int.生成非cdef类时,Cython不会填充这些插槽. 这些的优点是(对于C/C++ython类)找到 相反, >对于调用__setitem__的Python类,它改为uses a default implementation,它对字符串“__setitem__”进行字典查找. 请注意,如果setitem常规函数要在cdef类中定义为cpdef(并从Cython中调用),那么Cython会实现自己的机制以便快速查找. 呼唤效率 找到属性后必须调用它.在从PyTypeObject中检索特殊函数的地方(例如cdef类中的__setitem__和__len__),它们只是C函数指针,因此可以直接调用. 对于每个其他情况,必须对从属性查找中检索的PyObject进行求值,以查看它是否可调用,然后调用. 退货处理 当从PyTypeObject作为特殊函数调用__setitem__时,返回值是一个int,它只是用作错误标志.不需要引用计数或处理Python对象. 当从PyTypeObject作为特殊函数调用__len__时,返回类型是Py_ssize_t,必须将其转换为Python对象,然后在不再需要时销毁. 对于普通函数(例如,从Python或Cython类调用的setitem,或Python类中定义的__setitem__),返回值是PyObject *,必须对其进行适当的引用计数/销毁. 总之,差异实际上与查找和调用函数的快捷方式有关,而不是函数的内容是否是Cython化. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |