Python 性能与timeit不一致
为清晰起见进行编辑:本质上我想知道的是在共享Linux机器上可以采取哪些步骤来确保Python代码的性能尽可能一致?Python 性能与timeit不一致,python,linux,performance,cython,Python,Linux,Performance,Cython,为清晰起见进行编辑:本质上我想知道的是在共享Linux机器上可以采取哪些步骤来确保Python代码的性能尽可能一致? 我正在尝试使用timeit模块确定两段不同代码中速度更快的代码。不幸的是,结果如此多变,我不知道哪一个更好 这里的两段代码是a)用Cython编译的Numpy函数和b)用Cython编译的类C函数。它们基本上会生成一组随机数,并将它们放入一个数量(部分)的箱子中。(不涉及对磁盘的读/写,所以这不是我的问题。)我在测试期间运行这两个函数20次,然后重复测试200次,从这200个测
我正在尝试使用
timeit
模块确定两段不同代码中速度更快的代码。不幸的是,结果如此多变,我不知道哪一个更好
这里的两段代码是a)用Cython编译的Numpy函数和b)用Cython编译的类C函数。它们基本上会生成一组随机数,并将它们放入一个数量(部分
)的箱子中。(不涉及对磁盘的读/写,所以这不是我的问题。)我在测试期间运行这两个函数20次,然后重复测试200次,从这200个测试中选择最佳时间
为了测试这两个函数的速度,我正在运行的Python代码如下所示:
import timeit
num = 20
repeat = 200
setup = '''import my_cython_code as sc
parts = 100'''
print "pyx: ", min(timeit.repeat('sc.pyx(parts)',
number=num, setup=setup, repeat=repeat))
print "c: ", min(timeit.repeat('sc.c(parts)',
number=num, setup=setup, repeat=repeat))
print "pyx: ", min(timeit.repeat('sc.pyx(parts)',
number=num, setup=setup, repeat=repeat))
print "c: ", min(timeit.repeat('sc.c(parts)',
number=num, setup=setup, repeat=repeat))
print "pyx: ", min(timeit.repeat('sc.pyx(parts)',
number=num, setup=setup, repeat=repeat))
print "c: ", min(timeit.repeat('sc.c(parts)',
number=num, setup=setup, repeat=repeat))
print "pyx: ", min(timeit.repeat('sc.pyx(parts)',
number=num, setup=setup, repeat=repeat))
print "c: ", min(timeit.repeat('sc.c(parts)',
number=num, setup=setup, repeat=repeat))
print "pyx: ", min(timeit.repeat('sc.pyx(parts)',
number=num, setup=setup, repeat=repeat))
当我运行此命令时,我得到如下输出:
pyx: 0.00450992584229
c: 0.00507998466492
pyx: 0.00416111946106
c: 0.0036518573761
pyx: 0.00330686569214
c: 0.00355005264282
pyx: 0.00322699546814
c: 0.00346803665161
pyx: 0.00327897071838
为什么会有这么多的变化?如何确保性能更加一致?我正在安装了Scientific Linux 6.6版的共享机器上运行代码。(我不是管理员,因此无法停止其他人的进程/等以测试性能。)
注意:我理解在这种情况下,两个函数的速度几乎相同,因此我的努力可能有点误入歧途 通常我会使用一个更大的
parts
,大约在10000-100000之间,这使得这两个函数的速度都慢得多(~O(n))。对于较大的值,这两个函数之间可能存在更显著的差异——这就是我感兴趣的。在本例中,我使用较小的值来进行演示,这比任何东西都重要
不幸的是,由于性能不一致,我无法判断哪个更快,因此出现了这个问题
以下是高性能Mark的建议:
pyx: min: 0.004488 max: 0.008562 avg: 0.005900 std: 0.001607
c: min: 0.005030 max: 0.005783 avg: 0.005304 std: 0.000149
pyx: min: 0.004416 max: 0.006408 avg: 0.004995 std: 0.000382
c: min: 0.004878 max: 0.005824 avg: 0.005357 std: 0.000184
pyx: min: 0.004481 max: 0.005147 avg: 0.004721 std: 0.000130
c: min: 0.005025 max: 0.005717 avg: 0.005277 std: 0.000145
pyx: min: 0.003409 max: 0.004910 avg: 0.004073 std: 0.000508
c: min: 0.003712 max: 0.005244 avg: 0.004436 std: 0.000497
平均值在大多数情况下更稳定,但我偶尔仍然会得到奇怪的性能,如上所述
使用num=1000
和repeat=50
:
pyx: min: 0.022578 max: 0.036049 avg: 0.026740 std: 0.005088
c: min: 0.024303 max: 0.029202 avg: 0.027013 std: 0.001051
pyx: min: 0.022904 max: 0.025746 avg: 0.024109 std: 0.000616
c: min: 0.018185 max: 0.026352 avg: 0.020287 std: 0.002845
pyx: min: 0.016775 max: 0.017728 avg: 0.017132 std: 0.000195
c: min: 0.018132 max: 0.020774 avg: 0.019203 std: 0.000714
pyx: min: 0.016763 max: 0.017589 avg: 0.017049 std: 0.000186
c: min: 0.017587 max: 0.021777 avg: 0.018697 std: 0.001005
@HighPerformanceMark-我添加了一个mean和st.dev示例。在我看来,您应该在测试中使用更高的数字。在数字相对较低的情况下,实际计时迭代的成本和其他系统因素在整个运行时中所占的比例会越来越大。@mgilson如果我使用
num=1000
和repeat=50
运行,我仍然会遇到同样的问题。无论是哪种方式,num
和repeat
都会受到我执行正确测试时函数运行时间的限制(使用parts=100000
左右)。@HighPerformanceMark我刚刚发布的最后一个示例显示了更多的奇怪行为。如果这是我能做的最好的,我会接受它,但是我能做的就是给我更一致的结果吗?@HighPerformanceMark实际上我是目前唯一在计算机上运行任何东西的人。我用nice19运行了16个Python进程,我们的计算机上有24个内核,所以(理论上)它们不应该干扰太多。我想我可以尝试以某种方式冻结它们,但这似乎不是一个可行的长期解决方案(例如,我不希望每次运行性能检查时都必须冻结/解冻我的所有进程),并且如果其他用户有正在运行的进程(我无法以非管理员身份冻结这些进程),则无法工作。