Programing

Python3에 xrange 함수가없는 이유는 무엇입니까?

lottogame 2020. 4. 3. 08:08
반응형

Python3에 xrange 함수가없는 이유는 무엇입니까?


최근에 Python3을 사용하기 시작했으며 xrange 상처가 부족합니다.

간단한 예 :

1) 파이썬 2 :

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) 파이썬 3 :

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 % 더 느립니다. 영업 이익은 어떻게 2 배나 느려졌습니까? 글쎄, 32 비트 파이썬으로 동일한 테스트를 반복하면 1.58 대 3.12를 얻습니다. 그래서 이것은 32 비트를 손상시키는 방식으로 3.x가 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전체 반복보다 두 배 이상의 시간이 소요됩니다.

그리고 "파이썬 2.6+보다 훨씬 더 많은 리소스를 소비한다"고 평가 한 결과, 3.x range는 2.x xrange정확히 같은 크기 인 것 같습니다. 범위 반복이 할 수있는 것보다 여전히 약 10000000 배 더 많은 문제입니다.

그리고 for내부의 C 루프 대신 명시 적 루프는 deque어떻습니까?

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.3range2.7xrange 입니다. 당신은 심지어 변경 내역을 볼 수 있습니다 (파일의 어느 곳에서나 문자열 "xrange"의 마지막 인스턴스를 대체 한 변경 사항에 연결되어 있다고 생각합니다).

그렇다면 왜 느려 집니까?

글쎄, 그들은 많은 새로운 기능을 추가했습니다. 다른 경우에는 사소한 부작용이있는 모든 장소 (특히 반복 내부)에서 모든 종류의 변경을 수행했습니다. 그리고 때로는 덜 중요한 경우를 약간 비관 화하더라도 다양한 중요한 경우를 극적으로 최적화하기위한 많은 작업이있었습니다. 이 모든 것을 합하면 가능한 range한 빨리 반복하는 것이 조금 느리다는 사실에 놀라지 않습니다 . 아무도 그다지 집중하지 않을 정도로 덜 중요한 경우 중 하나입니다. 이 성능 차이가 코드의 핫스팟 인 실제 사용 사례는 아무도 없습니다.


Python3의 범위 Python2의 xrange입니다. 주위에 iter를 감쌀 필요가 없습니다. Python3에서 실제 목록을 얻으려면list(range(...))

Python2 및 Python3에서 작동하는 것을 원한다면 이것을 시도하십시오

try:
    xrange
except NameError:
    xrange = range

Python 3의 range유형은 Python 2와 동일하게 작동합니다 xrange. xrange함수에서 반환 된 반복자 range직접 반복하면 얻을 수있는 것이기 때문에 왜 느려지는 지 잘 모르겠습니다 .

시스템 속도 저하를 재현 할 수 없습니다. 내가 테스트 한 방법은 다음과 같습니다.

파이썬 2 xrange:

Python 2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import timeit
>>> timeit.timeit("[x for x in xrange(1000000) if x%4]",number=100)
18.631936646865853

Python 3 range은 조금 더 빠릅니다.

Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) [MSC v.1600 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import timeit
>>> timeit.timeit("[x for x in range(1000000) if x%4]",number=100)
17.31399508687869

내가 최근 파이썬 3의 사실을 알게 range유형은 슬라이스에 대한 지원과 같은 다른 깔끔한 기능을 가지고 range(10,100,2)[5:25:5]있다 range(20, 60, 10)!


python2 코드를 수정하는 한 가지 방법은 다음과 같습니다.

import sys

if sys.version_info >= (3, 0):
    def xrange(*args, **kwargs):
        return iter(range(*args, **kwargs))

Python 2의 xrange는 생성기이며 iterator를 구현하는 반면 range는 단지 함수입니다. 파이썬 3에서는 왜 xrange에서 빠졌는지 모르겠습니다.


comp : ~ $ python Python 2.7.6 (디폴트, 2015 년 6 월 22 일, 17:58:13) [linux2의 [GCC 4.8.2]

>>> import timeit
>>> timeit.timeit("[x for x in xrange(1000000) if x%4]",number=100)

5.656799077987671

>>> timeit.timeit("[x for x in xrange(1000000) if x%4]",number=100)

5.579368829727173

>>> timeit.timeit("[x for x in range(1000000) if x%4]",number=100)

21.54827117919922

>>> timeit.timeit("[x for x in range(1000000) if x%4]",number=100)

22.014557123184204

timeit 번호가 1 인 매개 변수 :

>>> timeit.timeit("[x for x in range(1000000) if x%4]",number=1)

0.2245171070098877

>>> timeit.timeit("[x for x in xrange(1000000) if x%4]",number=1)

0.10750913619995117

comp : ~ $ python3 Python 3.4.3 (디폴트, 2015 년 10 월 14 일, 20:28:29) [GCC 4.8.4] Linux에서

>>> timeit.timeit("[x for x in range(1000000) if x%4]",number=100)

9.113872020003328

>>> timeit.timeit("[x for x in range(1000000) if x%4]",number=100)

9.07014398300089

timeit number = 1,2,3,4 매개 변수를 사용하면 빠르고 선형 적으로 작동합니다

>>> timeit.timeit("[x for x in range(1000000) if x%4]",number=1)

0.09329321900440846

>>> timeit.timeit("[x for x in range(1000000) if x%4]",number=2)

0.18501482300052885

>>> timeit.timeit("[x for x in range(1000000) if x%4]",number=3)

0.2703447980020428

>>> timeit.timeit("[x for x in range(1000000) if x%4]",number=4)

0.36209142999723554

그래서 우리가 timeit.timeit ( "[x % 4의 경우 x (1000000) x x x4 %]], number = 1)"와 같이 1 개의 실행 루프 사이클을 측정하면 python3은 충분히 빠르게 작동합니다. 그러나 반복 루프에서 파이썬 2 xrange ()는 파이썬 3의 range ()에 비해 속도가 빠릅니다.

참고 URL : https://stackoverflow.com/questions/15014310/why-is-there-no-xrange-function-in-python3

반응형