【发布时间】:2014-10-04 22:42:47
【问题描述】:
也许我在做一些奇怪的事情,但在使用 numpy 时可能会发现令人惊讶的性能损失,无论使用何种功率似乎都是一致的。例如当 x 是一个随机的 100x100 数组时
x = numpy.power(x,3)
比
慢大约 60 倍x = x*x*x
各种阵列大小的加速图显示了阵列大小约为 10k 的最佳点,而其他大小的阵列速度一致地提高了 5-10 倍。
在你自己的机器上测试下面的代码(有点乱):
import numpy as np
from matplotlib import pyplot as plt
from time import time
ratios = []
sizes = []
for n in np.logspace(1,3,20).astype(int):
a = np.random.randn(n,n)
inline_times = []
for i in range(100):
t = time()
b = a*a*a
inline_times.append(time()-t)
inline_time = np.mean(inline_times)
pow_times = []
for i in range(100):
t = time()
b = np.power(a,3)
pow_times.append(time()-t)
pow_time = np.mean(pow_times)
sizes.append(a.size)
ratios.append(pow_time/inline_time)
plt.plot(sizes,ratios)
plt.title('Performance of inline vs numpy.power')
plt.ylabel('Nx speed-up using inline')
plt.xlabel('Array size')
plt.xscale('log')
plt.show()
有人解释一下吗?
【问题讨论】:
-
附带说明,您真的,真的不应该使用
time作为计时码。time的文档甚至会告诉你这一点。在某些平台上,在某些情况下,它可能已经足够好了……但还是使用timeit更好。 -
一般来说,一个通用的幂方法,接受基数和指数的任意值(尤其是非整数)将需要更复杂的工作。然而,一个简单的
x*x*x可以很容易地使用操作码来表达,操作码本身可以很容易地翻译成实际的机器代码。 -
@MikeGraham:我不明白你的回答。
timeit是您分析代码的方式;它实际上比time更容易使用,而且更可能是正确的。 (如果你使用 IPython 和它的魔力%timeit,更是如此。) -
@MikeGraham:你是否回应了其他人的评论(后来被删除了)建议围绕
power展开小整数的包装函数,并且只输入我的名字而不是那个人的名字?如果是这样,那么是的,你可能是对的。 -
@abarnert,我是想回复 Newmu 对我的帖子的评论……我不知道我是怎么搞得这么混乱的。
标签: python arrays performance numpy