0

我有一个脚本可以唤起一个“for 循环”,其中迭代次数(1000)超过一百万次。我已经阅读了 range() vs xrange() 线程,并且我知道我不想做这样的事情。

for o in xrange(1000000):
    for i in range(1000): #Definitely do not want
        pass              

相反,我希望创建一个包含 1000 个元素的对象,然后使用它来不断迭代。

方法一:

iterate=range(1000)
for o in xrange(1000000):
    for i in iterate:    #<---
        pass

方法二:

for o in xrange(1000000):
    for i in xrange(1000):    #<----
        pass

我想知道哪种方法会在“for 循环”中提供更好的性能。谢谢你。

编辑:对不起。我相信我不清楚。我的问题是我是否应该使用已经创建的列表或使用 xrange() 来使我正在调用的这个内部循环获得更好的性能。

4

5 回答 5

3

一些本地测试结果:

>>> timeit.timeit('for i in repeat(None, 1000): pass', setup='from itertools import repeat', number=100000)
1.94118924332561
>>> timeit.timeit('for i in xrange(1000): pass', number=100000)
2.5231991775491025
>>> timeit.timeit('for i in range(1000): pass', number=100000)
3.9302601308266816
>>> timeit.timeit('for i in r: pass', setup='r = [None] * 1000', number=100000)
2.0900103923822684
>>> timeit.timeit('for i in r: pass', setup='r = range(1000)', number=100000)
2.2248894063351656
>>> timeit.timeit('for i in r: pass', setup='r = xrange(1000)', number=100000)
2.9105822108675823

您不能对它使用缓存itertools.repeat,因为该迭代器的行为就像一个生成器(您只能“读取”一次值,然后它们就消失了)。

重复1或类似的事情可能会无限快,因为None不再需要查找名称,但是任何此类性能优势都会在测试结果随机变化的噪音中丢失。

于 2012-05-01T15:56:24.603 回答
2

xrange在 Python 2.x 和range3.x 中,不在内存中构建列表,因此如果您只想迭代这些值,这是最佳选择。但是,使用列表表达式构建临时列表会破坏目的。相反,您只想:

for i in xrange(1000): # range in Python 3.x
    pass

对于像 1000 这样的小数字,这不太可能显着影响性能(2.x 文档over的优势是最小的xrangerange)。相反,对您的程序进行基准测试并找出哪个部分速度较慢。

于 2012-05-01T15:20:43.330 回答
2

xrange()消耗的内存比range(). 它也更快:

In [1]: %timeit for i in range(1000): pass

10000 loops, best of 3: 28.8 us per loop

In [2]: %timeit for i in xrange(1000): pass

100000 loops, best of 3: 18.3 us per loop

(Linux 上的 64 位 Python 2.7.2。)

注意上面xrange()直接使用。您的第二个代码片段(带有 withiterate的那个)否定了使用的好处,xrange()应该避免使用。

于 2012-05-01T15:19:24.013 回答
0

它的表现值得。这样做的好处xrange是,它返回一个可迭代对象,这意味着它不会创建 N 个元素的列表并返回它(如range):

def xrange(n):
    i = 0
    while i < n:
        yield i

xrange 看起来与此类似。所以你的LCiterate = [x for x in xrange(1000)]等于iterate = range(1000)

正确的代码是:

for i in xrange(1000):
    pass
于 2012-05-01T15:21:52.927 回答
0

xrange 将为您提供更好的性能,因为它不必在迭代之前分配整个结果列表。这导致更好的数据缓存一致性等。

编辑:查看您的示例,您两次都在创建列表。然后我会说,在您给出的情况下,使用 range 会更高效,因为它致力于创建范围列表,而不是通过 xrange 使用列表推导来创建列表。

于 2012-05-01T15:19:29.800 回答