如何弄清楚为什么cython-izing代码会降低它的速度?

时间:2012-05-22 22:57:21

标签: python optimization cython

我们有一些用python编写的代码,它使用的几个类实际上只是“结构” - 这些类的实例只包含一堆字段而没有方法。例如:

class ResProperties:
    def __init__(self):
        self.endDayUtilities = 0
        self.marginalUtilities = []
        self.held = 0
        self.idleResource = True
        self.experience = 0.0
        self.resSetAside = 0
        self.unitsGatheredToday = 0

我们的主要代码使用了这个类的一堆实例。

为了加快代码速度,我想我已经将这个课程编程了:

cdef class ResProperties:

    cdef public float endDayUtilities
    cdef public list marginalUtilities
    cdef public int held
    cdef public int idleResource
    cdef public float experience
    cdef public int resSetAside
    cdef public int unitsGatheredToday

    def __init__(self):
        self.endDayUtilities = 0
        # etc: code just like above.

然而,结果是代码现在运行速度慢了25%!

如何找出导致代码运行速度变慢的原因?

感谢。

1 个答案:

答案 0 :(得分:5)

您已将这些类转换为Cython但仍在Python代码中使用它们吗?

将数据从C转换为Python并返回将导致开销。例如,您的endDayUtilities成员是C样式的浮点数。当您从Python访问它时,必须先构造float()对象,然后Python代码才能对其执行任何操作。当您从Python分配该属性时,同样的事情必须反过来。

在我的脑海中,我估计这些数据转换的性能开销为......哦,大约25%。 : - )

在将使用该数据的代码移动到Cython之前,您不会看到性能提升。基本上,你可以留在C-land越多,你就会越好。来回走动会杀了你。

另一种更简单的方法,你可能想尝试Psyco或PyPy而不是Cython。