sus*_*its 11 python performance
for i in xrange(...)在Python中提倡使用-style循环结构的理由是什么?对于简单的整数循环,开销的差异很大.我使用两段代码进行了一个简单的测试:
档案idiomatic.py:
#!/usr/bin/env python
M = 10000
N = 10000
if __name__ == "__main__":
x, y = 0, 0
for x in xrange(N):
for y in xrange(M):
pass
Run Code Online (Sandbox Code Playgroud)
档案cstyle.py:
#!/usr/bin/env python
M = 10000
N = 10000
if __name__ == "__main__":
x, y = 0, 0
while x < N:
while y < M:
y += 1
x += 1
Run Code Online (Sandbox Code Playgroud)
分析结果如下:
bash-3.1$ time python cstyle.py
real 0m0.109s
user 0m0.015s
sys 0m0.000s
bash-3.1$ time python idiomatic.py
real 0m4.492s
user 0m0.000s
sys 0m0.031s
Run Code Online (Sandbox Code Playgroud)
我可以理解为什么Pythonic版本更慢 - 我想它与调用xrange N次有很大关系,如果有一种方法可以倒回生成器,也许这可以消除.但是,由于执行时间的这种差异,为什么人们更喜欢使用Pythonic版本?
编辑:我使用Martelli先生提供的代码再次进行了测试,现在结果确实更好:
我以为我会在这里列举一下这个帖子的结论:
1)模块范围内的大量代码是个坏主意,即使代码包含在if __name__ == "__main__":块中也是如此.
2)*奇怪的是,修改属于thebadone我的错误版本的代码(让y增长而不重置)在性能上几乎没有差异,即使对于较大的M和N值也是如此.
Ale*_*lli 22
这是正确的比较,例如在loop.py中:
M = 10000
N = 10000
def thegoodone():
for x in xrange(N):
for y in xrange(M):
pass
def thebadone():
x = 0
while x < N:
y = 0
while y < M:
y += 1
x += 1
Run Code Online (Sandbox Code Playgroud)
所有重要的代码都应该始终存在于函数中 - 在模块的顶层放置一亿个循环显示鲁莽地忽略性能并且嘲弄任何测量所述性能的尝试.
完成后,您会看到:
$ python -mtimeit -s'import loop' 'loop.thegoodone()'
10 loops, best of 3: 3.45 sec per loop
$ python -mtimeit -s'import loop' 'loop.thebadone()'
10 loops, best of 3: 10.6 sec per loop
Run Code Online (Sandbox Code Playgroud)
所以,正确衡量,你倡导的坏方法比Python推广的好方式慢约3倍.我希望这会让你重新考虑你的错误宣传.
Gle*_*ard 11
您忘记在内循环后将y重置为0.
#!/usr/bin/env python
M = 10000
N = 10000
if __name__ == "__main__":
x, y = 0, 0
while x < N:
while y < M:
y += 1
x += 1
y = 0
Run Code Online (Sandbox Code Playgroud)
编辑:修复后的20.63s与使用xrange的6.97s