为什么Python3中没有xrange函数?

为什么Python3中没有xrange函数?,第1张

为什么Python3中没有xrange函数?

进行一些性能评估,

timeit
而不是尝试使用手动进行
time

首先,Apple 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 loopIn [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 loopIn [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

range
确实比2.x慢一些
xrange
。OP的
xrange
功能与此无关。(不足为奇,因为
__iter__
在循环中发生的任何事情的1000万次调用中,对插槽的一次性调用不太可能看到,但有人提出来了。)

但这仅慢了30%。OP如何使速度慢2倍?好吧,如果我对32位Python重复相同的测试,则得出的结果是1.58和3.12。因此,我的猜测是,这是3.x针对64位性能进行了优化(以损害32位的方式)的又一案例

但这真的重要吗?再次使用64位3.3.0进行检查:

In [86]: %timeit [x for x in range(10000000) if x%4 == 0]1 loops, best of 3: 3.65 s per loop

因此,构建所需的

list
时间是整个迭代的两倍以上。

至于“比Python
2.6+消耗更多的资源”,在我的测试中,看起来3.x

range
大小与2.x的大小完全相同
xrange
,即使它的大小是10x的大小,也可以构建不必要的列表问题仍然比范围迭代可能做的任何事情多出10000000x。

那么显式

for
循环而不是内部的C循环
deque
呢?

In [87]: def consume(x):   ....:     for i in x:   ....:         passIn [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
range
是被删除的。

这是3.3

range
对象是2.x
xrange
对象(而不是2.x
range
函数)的直接后代的证明:3.3
range
和2.7
xrange
的源。您甚至可以查看更改历史记录(我相信,该更改已链接到替换文件中任何位置的字符串“
xrange”的最后一个实例的更改)。

那么,为什么它变慢?

好吧,其中之一是,他们添加了许多新功能。另一方面,他们已经在整个地方(尤其是在迭代过程中)进行了各种具有较小副作用的更改。尽管有时有时会稍微低估不太重要的案例,但仍进行了大量工作来显着优化各种重要案例。将所有这些加起来,

range
对于尽快进行迭代现在变得慢一点,我并不感到惊讶。这是最重要的案例之一,没有人会足够关注。没有人会遇到现实生活中的用例,这种性能差异是他们代码中的热点。



欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5643712.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-16
下一篇2022-12-16

发表评论

登录后才能评论

评论列表(0条)

    保存