python - Python 2.7 中的对象实例化速度极慢

标签 python performance python-2.7 overhead

我最近不得不完成一项使用大量坐标操作的作业。为了节省时间和简化我的代码,我定义了一个类来封装坐标对的行为。该类看起来像这样:

class Vector (tuple) :
    def __init__ (self, value) :
        tuple.__init__ (self, value)


    def __add__ (self, other) :
        return Vector ((self [0] + other [0], self [1] + other [1]))

这让我可以编写这样的代码(例如):

def translate (pointList, displacement) :
    return [point + displacement for point in pointList]

但是我的应用程序非常慢。比其他任务慢得多。我无法在我的算法实现中找到任何低效之处,所以我做了一个简单的测试来查看 Vector 类的开销是多少。我预计在 5% 到 15% 之间。

我对 Vector 类的测试如下所示:

v = Vector ((0, 0))
d = Vector ((1, -1))
loopIdx = 3000000
while loopIdx > 0 :
    v = v + d
    loopIdx -= 1
print (v)

这(通常)在这种时间运行:

real    0m8.440s
user    0m8.367s
sys     0m0.016s

为了比较,我运行了这段代码:

v = (0, 0)
dX = 1
dY = -1
loopIdx = 3000000
while loopIdx > 0 :
    v = ( v [0] + dX, v [1] + dY )
    loopIdx -= 1
print (v)

这段代码的运行时间是:

real    0m1.004s
user    0m0.995s
sys     0m0.006s

我是不是做错了什么,或者在 Python 中使用类对象真的意味着您的应用程序将花费 8 倍多的时间来运行吗?

最佳答案

不是真正的答案如何让你上课更快,而是更多的选择。

与其继承 tuple 并自己编写所有这些 addsub 等方法,不如使用 Python 的 bultin complex 二维坐标的数字类型,它已经内置了所有这些操作,正确且超快。

>>> %timeit vector_no_init()
1 loops, best of 3: 1.39 s per loop
>>> %timeit plain_tuple()
1 loops, best of 3: 403 ms per loop
>>> %timeit complex_nums()
1 loops, best of 3: 171 ms per loop

对于旋转,您可以使用复数乘法:只需将您的复数坐标乘以一个复数,该复数的极坐标形式绝对值为 1,相位等于您要旋转的角度。 要旋转 90 度,只需乘以 1j(逆时针)或 -1j(顺时针)。对于所有其他角度,请使用 cmath用于从极坐标形式转换的模块。

>>> c = complex(4, 2)
>>> c * cmath.rect(1, math.radians(45))
(1.4142135623730954+4.242640687119285j)

但是,我建议不要complex 子类化,以使 rotate 成为该类的方法,因为在这种情况下,您将不得不覆盖所有其他方法,如add,以及,否则加法的结果将是一个规则的复数,不提供rotate方法。这会抵消所有这些性能提升,使其与您的 Vector 类一样慢。相反,只需创建一个函数 rotate(complex, angle) -> complex

关于python - Python 2.7 中的对象实例化速度极慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31072340/

相关文章:

python-2.7 - Matlab 的 stdfilt() 函数的 python 等价物是什么?

python - 如果我将元素放入括号中,则乘法为零(python)

python - 根据另一列的信息用 Pandas 填充一个空列

java - rhel 7.4 上的 ibm java 太慢了

performance - 一阶公式中变量的有效重命名

python - 函数列 Python

python - 如何在Python中找到单词旁边的单词

python - 在 SQLAlchemy 基类中定义抽象方法

python - 给定 N 项列表,如何生成长度为 LEN 的排列?

python - numpy 怎么能比我的 Fortran 例程快得多?