为什么list(xrange)比range()慢?

Rus*_*hal 2 python performance python-2.7

我做了几个测试,发现它xrange()range()(通过各种问题/答案证实的)快得多:

>>> from timeit import timeit
>>> timeit(stmt = 'x = range(1000)', number = 10000)
0.38216601211680734
>>> timeit(stmt = 'x = xrange(1000)', number = 10000)
0.010537726631953959 # xrange is much faster than range
Run Code Online (Sandbox Code Playgroud)

我很好奇,所以我尝试了另一个测试,看看是否list(xrange(1000))仍然比简单更快range(1000):

>>> timeit(stmt = 'x = range(1000)', number = 10000)
0.3858838963796529
>>> timeit(stmt = 'x = list(xrange(1000))', number = 10000)
0.492734766028903 # now, xrange is slower
Run Code Online (Sandbox Code Playgroud)

对于更多呼叫也是如此:

>>> timeit(stmt = 'x = range(1000)', number = 100000)
3.6457308233315757
>>> timeit(stmt = 'x = list(xrange(1000))', number = 100000)
5.722031755612818
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是,为什么list(xrange)明显慢于range自身?

我看到上的缓慢这一问题list(),dict()和其他的构造方法,所以这是为什么list(xrange)这么多慢?

使用dis.dis(),我发现list(xrange)执行的计算比以下更多range:

>>> dis.dis('x = list(xrange(1000))')
          0 SETUP_LOOP      15648 (to 15651)
          3 SLICE+2        
          4 IMPORT_NAME     29545 (29545)
          7 LOAD_GLOBAL     30760 (30760)
         10 POP_JUMP_IF_FALSE 28257
         13 BUILD_LIST      10341
         16 <49>           
         17 <48>           
         18 <48>           
         19 <48>           
         20 STORE_SLICE+1  
         21 STORE_SLICE+1  
>>> dis.dis('x = range(1000)')
          0 SETUP_LOOP      15648 (to 15651)
          3 SLICE+2        
          4 POP_JUMP_IF_FALSE 28257
          7 BUILD_LIST      10341
         10 <49>           
         11 <48>           
         12 <48>           
         13 <48>           
         14 STORE_SLICE+1  
Run Code Online (Sandbox Code Playgroud)

jam*_*lak 6

当然range()会更快,当你想要的最终产品是一个范围内所有数字的列表时,所有range这些都在一个函数调用中.相对于list(xrange())它的负担list(..)与开销构造rangeiterator创建遍历对象xrange物体,其list(..)构造必须消耗.虽然range()立即构造列表,没有中间迭代器消耗......怎么可能被打败?主要区别在于:1个函数调用vs 2个,不太重要的是1个全局查询vs 2个.