测试for _ in range(n)
的替代方案(执行某些操作n
次,即使操作不依赖于n
的值)我注意到这种模式还有另一种表述更快,for _ in [""] * n
。
例如:
timeit('for _ in range(10^1000): pass', number=1000000)
返回16.4秒;
而,
timeit('for _ in [""]*(10^1000): pass', number=1000000)
需要10.7秒。
为什么[""] * 10^1000
比Python 3中的range(10^1000)
快得多?
使用Python 3.3完成所有测试
答案 0 :(得分:10)
您的问题是您输入错误timeit
。
您需要提供包含Python语句的timeit
个字符串。如果你这样做
stmt = 'for _ in ['']*100: pass'
查看stmt
的值。方括号内的引号字符与字符串分隔符匹配,因此它们被Python解释为字符串分隔符。由于Python连接相邻的字符串文字,您将看到您真正拥有的内容与'for _ in [' + ']*100: pass'
相同,后者为您提供'for _ in []*100: pass'
。
所以你的超快速"循环只是循环遍历空列表,而不是100个元素的列表。例如,尝试使用
进行测试stmt = 'for _ in [""]*100: pass'
答案 1 :(得分:10)
当迭代range()
时,会产生0到n
之间所有整数的对象;即使使用small integers having been cached,这也需要一小段时间。
另一方面,[None] * n
上的循环会生成{1}}对1个对象的引用,并且创建该列表的速度会快一些。
但是,n
对象使用远更少的内存,和更易于启动,这就是人们更喜欢使用它的原因。大多数代码都不必挤出性能的最后一滴。
如果您需要具有该速度,则可以使用不带内存的自定义迭代,使用带有第二个参数的itertools.repeat()
:
range()
至于你的时间测试,这些问题存在一些问题。
首先,您在from itertools import repeat
for _ in repeat(None, n):
时序循环中出错了;你没有嵌入两个引号,你连接了两个字符串并产生了一个空列表:
['']*n
当你迭代0次时,它在迭代中将是无与伦比的。
你也没有使用大数字; >>> '['']*n'
'[]*n'
>>> []*100
[]
是二进制XOR运算符,而不是幂运算符:
^
这意味着您的测试错过了创建大空值列表所需的时间。
使用更好的数字和>>> 10^1000
994
可以获得:
None