나는 그것이 파이썬 2와 3 max
의 sort
함수 보다 느리다 는 것을 발견했습니다 .
파이썬 2
$ python -m timeit -s 'import random;a=range(10000);random.shuffle(a)' 'a.sort();a[-1]'
1000 loops, best of 3: 239 usec per loop
$ python -m timeit -s 'import random;a=range(10000);random.shuffle(a)' 'max(a)'
1000 loops, best of 3: 342 usec per loop
파이썬 3
$ python3 -m timeit -s 'import random;a=list(range(10000));random.shuffle(a)' 'a.sort();a[-1]'
1000 loops, best of 3: 252 usec per loop
$ python3 -m timeit -s 'import random;a=list(range(10000));random.shuffle(a)' 'max(a)'
1000 loops, best of 3: 371 usec per loop
( )이 함수 ( ) 보다 느린 이유 는 무엇 입니까?max
O(n)
sort
O(nlogn)
답변
timeit
파이썬 에서 모듈을 사용할 때 매우 조심해야합니다 .
python -m timeit -s 'import random;a=range(10000);random.shuffle(a)' 'a.sort();a[-1]'
여기서 초기화 코드는 무작위 배열을 생성하기 위해 한 번 실행됩니다. a
. 그런 다음 나머지 코드가 여러 번 실행됩니다. 처음에는 배열을 정렬하지만 다른 때마다 이미 정렬 된 배열에서 정렬 메서드를 호출합니다. 가장 빠른 시간 만 반환되므로 Python이 이미 정렬 된 배열을 정렬하는 데 걸리는 시간을 실제로 측정합니다.
파이썬의 정렬 알고리즘의 일부는 배열이 이미 부분적으로 또는 완전히 정렬되었는지 감지하는 것입니다. 완전히 정렬되면이를 감지하기 위해 어레이를 한 번만 스캔 한 다음 중지합니다.
대신 시도한 경우 :
python -m timeit -s 'import random;a=range(100000);random.shuffle(a)' 'sorted(a)[-1]'
그런 다음 정렬은 모든 타이밍 루프에서 발생하며 배열을 정렬하는 데 걸리는 시간이 단순히 최대 값을 찾는 것보다 훨씬 길다는 것을 알 수 있습니다.
편집 : @skyking의 대답 은 내가 설명하지 않은 부분을 설명합니다 a.sort()
. 목록에서 작업 중이므로 요소에 직접 액세스 할 수 있습니다. max(a)
임의의 이터 러블에서 작동하므로 일반 이터 레이션을 사용해야합니다.
답변
먼저 max()
반복자 프로토콜 을 사용하고 list.sort()
임시 코드 를 사용합니다 . 분명히 반복자를 사용하는 것은 중요한 오버 헤드이므로 타이밍의 차이를 관찰하는 것입니다.
그러나 그 외에는 테스트가 공정하지 않습니다. a.sort()
동일한 목록에서 두 번 이상 실행 중 입니다. 파이썬 사용 알고리즘 특히 빠른 이미 용으로 설계된다 (부분적) 데이터를 분류. 테스트에 따르면 알고리즘이 제대로 작동하고 있습니다.
다음은 공정한 테스트입니다.
$ python3 -m timeit -s 'import random;a=list(range(10000));random.shuffle(a)' 'max(a[:])'
1000 loops, best of 3: 227 usec per loop
$ python3 -m timeit -s 'import random;a=list(range(10000));random.shuffle(a)' 'a[:].sort()'
100 loops, best of 3: 2.28 msec per loop
여기에서는 매번 목록의 복사본을 만듭니다. 보시다시피 결과의 크기는 우리가 예상하는대로 마이크로 초와 밀리 초로 다릅니다.
그리고 기억하세요 : big-Oh는 상한을 지정합니다! 파이썬 정렬 알고리즘의 하한은 Ω ( n )입니다. O ( n log n )이된다고해서 모든 실행이 n log n에 비례하는 시간이 걸린다는 것을 자동으로 의미하지는 않습니다 . 그것은 O ( n ) 알고리즘 보다 느려 야한다는 것을 의미조차하지 않지만 그것은 또 다른 이야기입니다. 이해해야 할 중요한 것은 일부 유리한 경우 O ( n log n ) 알고리즘이 O ( n ) 시간 이하로 실행될 수 있다는 것 입니다.
답변
이는 while l.sort
의 멤버 가 일반 함수 이기 때문일 수 있습니다 . 이것은 while 의 내부 표현에 의존 할 수 있다는 것을 의미 하며 일반 반복기 프로토콜을 거쳐야합니다.list
max
l.sort
list
max
이것은 각 요소 가져 오기가 수행하는 각 요소 가져 오기 l.sort
보다 빠릅니다 max
.
대신 사용 sorted(a)
하면 결과가 max(a)
.