一些性能测量,使用timeit而不是试图手动使用时间。
首先,苹果2.7.2 64位:
In [37]: %timeit collections.deque((x for x in xrange(10000000) if x%4 == 0), maxlen=0)
1 loops, best of 3: 1.05 s per loop
现在,python.org 3.3.0 64位:
In [83]: %timeit collections.deque((x for x in range(10000000) if x%4 == 0), maxlen=0)
1 loops, best of 3: 1.32 s per loop
In [84]: %timeit collections.deque((x for x in xrange(10000000) if x%4 == 0), maxlen=0)
1 loops, best of 3: 1.31 s per loop
In [85]: %timeit collections.deque((x for x in iter(range(10000000)) if x%4 == 0), maxlen=0)
1 loops, best of 3: 1.33 s per loop
显然,3。X范围确实比2要慢一点。x xrange。OP的xrange函数与此无关。(这并不奇怪,因为对__iter__槽的一次性调用不太可能在对循环中发生的任何事情的10000000个调用中可见,但有人提出了这种可能性。)
但它只慢了30%。OP怎么慢了两倍?好吧,如果我用32位的Python重复同样的测试,我得到1.58 vs. 3.12。所以我猜这是3的另一种情况。X针对64位性能进行了优化,而这对32位性能不利。
但这真的重要吗?看看这个,3.3.0还是64位的:
In [86]: %timeit [x for x in range(10000000) if x%4 == 0]
1 loops, best of 3: 3.65 s per loop
因此,构建列表所花费的时间是整个迭代的两倍多。
至于“比Python 2.6+消耗更多的资源”,从我的测试来看,它看起来像3。X范围与2的大小完全相同。xrange—并且,即使它是它的10倍大,构建不必要的列表仍然比range迭代可能做的任何事情都要麻烦大约1000000倍。
用显式的for循环代替deque中的C循环呢?
In [87]: def consume(x):
....: for i in x:
....: pass
In [88]: %timeit consume(x for x in range(10000000) if x%4 == 0)
1 loops, best of 3: 1.85 s per loop
因此,在for语句中浪费的时间几乎和在迭代范围的实际工作中浪费的时间一样多。
如果您担心优化range对象的迭代,那么您可能找错地方了。
与此同时,你一直在问为什么xrange被删除了,不管人们告诉你多少次同样的事情,但我再重复一遍:它没有被删除:它被重命名为range,而2。X范围是被移除的部分。
下面是3.3 range对象是2的直接后代的一些证明。xrange对象(而不是2。X范围功能):源到3.3范围和2.7 xrange。您甚至可以看到更改历史(我相信是链接到替换文件中字符串“xrange”的最后一个实例的更改)。
那么,为什么它变慢了呢?
Well, for one, they've added a lot of new features. For another, they've done all kinds of changes all over the place (especially inside iteration) that have minor side effects. And there'd been a lot of work to dramatically optimize various important cases, even if it sometimes slightly pessimizes less important cases. Add this all up, and I'm not surprised that iterating a range as fast as possible is now a bit slower. It's one of those less-important cases that nobody would ever care enough to focus on. No one is likely to ever have a real-life use case where this performance difference is the hotspot in their code.