所有系统上Python中的执行时间不一致

时间:2014-07-15 15:20:37

标签: python performance

有些东西让我疯狂蟒蛇......我以前认为它是just Windows,但我错了。我可以使用相同的确切代码并多次运行它,并在不同的时间内执行。请使用以下测试代码,例如:

import math
def fib(count):
    x = 0
    while x < count:
        a = int(((((1 + math.sqrt(5)) / 2) ** x) - (((1 - math.sqrt(5)) / 2) ** (x))) / math.sqrt(5))
        x+=1

if __name__ == '__main__':  
    import timeit

    t = timeit.Timer("fib(1250)", setup="from __main__ import fib",)
    #print t.timeit(10)
    count = 10000
    results = t.repeat(count, 1)
    min = 0xFFFF
    max = 0
    sum = 0
    for i in results:
        i = i*1000.0
        if i < min: min = i
        if i > max: max = i
        sum+=i

    print "Min {:.3f} | Max {:.3f} | Max/Min {:.3f} | Avg {:.3f}".format(min, max, max/min, sum/count)

基本上,它会生成斐波那契的前1250个元素10,000次,并使用timeit来获取每次运行所花费的时间。然后我合并那些时间并找到最小值,最大值,平均值和最小值与最大值之间的差异(如果你愿意的话,差值)。

结果如下:

Windows: Min 3.071 | Max 8.903 | Max/Min 2.899 | Avg 3.228
Mac OS:  Min 1.531 | Max 3.167 | Max/Min 2.068 | Avg 1.621
Ubuntu:  Min 1.242 | Max 10.090 | Max/Min 8.123 | Avg 1.349

因此,Linux是最快但也有最多变化的。很多。但是所有这些都可以有一个非常疯狂的变化:Mac只有200%,Windows为290%,Linux为810%!

它实际上执行了那么多不同的时间吗?时间不够准确吗?还有其他我想念的东西吗?我在制作动画方面做了很多工作,我需要尽可能一致的时间。

2 个答案:

答案 0 :(得分:9)

你的测量时间很短,然后在某个地方发生的一些事情会产生很大的影响。

我在我的机器上运行了测试脚本(OS X,Core i7,Python 2.7)并制作了results的这个图:

enter image description here

你可以看到,大部分时间的时间结果非常一致,但是算法的孤立事件需要花费更多的时间(因为还有其他事情发生)。


我对你的计时程序进行了微调:

results=t.repeat(10, 1000)

所以,现在我们正在计时1000次函数调用。总时间是相同的,自然(10000个电话):

enter image description here

现在您可以看到性能更加可预测。可能是你的摆动时间的一部分是由于时间方法,而不是真正不同的时间来执行任何事情。在真实的OS环境中,毫秒级时序很难实现。即使你的计算机没有做任何事情,它仍在切换任务,做后台工作等等。


我理解原来的一点是不计算斐波纳契数。但如果是的话,那么选择合适的工具会有所不同:

import numpy as np

def fib(count):
    x = np.arange(count)
    a = (((1 + np.sqrt(5))/2) ** x - ((1 - np.sqrt(5)) / 2) ** x) / np.sqrt(5)
    a = a.astype('int')

这给出了:

Min 0.120 | Max 0.471 | Max/Min 3.928 | Avg 0.125

提高十倍速度。


关于此答案中的图像,它们与matplotlib一起绘制。第一个是这样做的:

import matplotlib.pyplot as plt

# create a figure
fig = plt.figure()
# create axes into the figure
ax = fig.add_subplot(111)
# plot the vector results with dots of size 2 (points) and semi-transparent blue color
ax.plot(results, '.', c=(0, 0, 1, .5), markersize=2)

请参阅matplotlib的文档。最简单的方法是使用IPythonpylab开始。

答案 1 :(得分:3)

我创建了一个类似于@drV的情节(给他投票,他是第一个!) - 不同之处在于我对结果进行了排序,因此您可以看到趋势线。提示是即使最大值很高,平均值也很低,所以最后会有一些异常值。

enter image description here

我使用pylab只是将它添加到底部:

from pylab import *
results.sort()
plot(range(len(results)),results)
show()