gpt4 book ai didi

python - 为什么 Python3 中没有 xrange 函数?

转载 作者:IT老高 更新时间:2023-10-28 12:10:58 24 4
gpt4 key购买 nike

最近我开始使用 Python3,缺少 xrange 很痛苦。

简单示例:

  1. Python2:

    from time import time as t
    def count():
    st = t()
    [x for x in xrange(10000000) if x%4 == 0]
    et = t()
    print et-st
    count()
  2. Python3:

    from time import time as t

    def xrange(x):

    return iter(range(x))

    def count():
    st = t()
    [x for x in xrange(10000000) if x%4 == 0]
    et = t()
    print (et-st)
    count()

结果分别是:

  1. 1.53888392448
  2. 3.215819835662842

这是为什么呢?我的意思是,为什么 xrange 已被删除?这是一个很好的学习工具。对于初学者,就像我自己一样,就像我们都在某个时候一样。为什么要删除它?谁能给我指出正确的 PEP,我找不到。

最佳答案

一些性能测量,使用 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 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 range 确实比 2.x xrange 慢了一点。并且OP的 xrange 函数与它无关。 (不足为奇,因为对 __iter__ 槽的一次性调用在 10000000 次循环中发生的任何调用中不太可能可见,但有人提出了它的可能性。)

但它只慢了 30%。 OP 是如何变得慢 2 倍的?好吧,如果我用 32 位 Python 重复相同的测试,我会得到 1.58 与 3.12。所以我的猜测是,这是 3.x 以损害 32 位的方式针对 64 位性能进行优化的又一个案例。

但这真的重要吗?检查一下,再次使用 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

因此,构建 list 所花费的时间是整个迭代的两倍多。

至于“消耗比 Python 2.6+ 更多的资源”,根据我的测试,看起来 3.x range 与 2.x xrange 的大小完全相同——而且,即使它有 10 倍大,构建不必要的列表仍然比范围迭代可能做的任何事情都要多 10000000 倍。

那么显式 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 range 就是被移除的内容。

这里有一些证据表明 3.3 range 对象是 2.x xrange 对象的直接后代(而不是 2.x range函数):3.3 range的来源和 2.7 xrange .你甚至可以看到change history (链接到,我相信,替换文件中任何地方的字符串“xrange”的最后一个实例的更改)。

那么,为什么它变慢了?

首先,他们添加了许多新功能。另一方面,他们在整个地方(尤其是内部迭代)进行了各种具有轻微副作用的更改。并且已经做了很多工作来显着优化各种重要的案例,即使它有时会略微悲观不太重要的案例。把这一切加起来,我并不感到惊讶的是,尽可能快地迭代 range 现在有点慢。这是没有人会足够关注的次要案例之一。没有人可能会遇到这样的实际用例,其中这种性能差异是他们代码中的热点。

关于python - 为什么 Python3 中没有 xrange 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15014310/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com