2010-07-17 4 views
9

저는 최근에 파이썬을 배우고 있으며 언어로 많은 연습을하고 있습니다.파이썬에서 왜 배열에서 읽는 것이 목록에서 읽는 것보다 느린 것일까 요?

내가 흥미로운 점 중 하나는 배열에서 읽을 때 목록보다 느린 시간이 거의 절반이라는 것입니다. 왜 누군가는 그 이유를 알고 있습니까?

 
from timeit import Timer 
import array 

t = 10000 
l = range(t) 
a = array.array('i', l) 
def LIST(): 
    for i in xrange(t): 
     l[i] 

def ARRAY(): 
    for i in xrange(t): 
     a[i] 

print Timer(LIST).timeit(1000); 
print Timer(ARRAY).timeit(1000); 

출력은 다음과 같습니다 :

여기 내 코드의

배열을 읽는 것은 목록보다 느린 것을 나타냅니다
 
0.813191890717 
1.16269612312 

. 배열은 고정 크기 메모리이고 목록은 동적 구조라고 생각합니다. 그래서 배열이 목록보다 빠를 것이라고 생각했습니다.

아무도 설명이 있습니까?

+1

dupe/answer : http://stackoverflow.com/questions/176011/python-list-vs-array-when-to-use - 기본적으로 array.array는 C 배열을 둘러싼 래퍼이므로 생각합니다. 액세스 할 때 오버 헤드가 발생합니다. 수학에 사용하지 마십시오. –

+0

파이썬 효율성을 두 번째 추측하려는 시도 - 특히 C와 유사한 배경에서 오는 경우 -는 대개 직관적이지 않습니다. 먼저 코드를 명확하게 작성한 다음 성능 문제를 측정하는 경우 최적화하십시오. 이것은 C에도 적용되지만, 언어 요소가 사람들이 자주 잊어 버리는 기계에 너무 가깝기 때문에. – msw

+1

수학에서는 numpy (아직 파이썬 3에서는 사용 가능하지 않음)를 사용할 수 있지만 numpy가 표준 라이브러리가 아닌 이유는 신만 알고 있습니다. –

답변

8

원시 정수를 파이썬 int으로 래핑하는 데 시간이 걸립니다.

+2

그렇습니다. 함수 LIST는 각 목록 요소에 대한 참조 카운트를 증가시키고 감소시켜야합니다. 반면에 ARRAY 함수는 각 정수 (최적화가있는 더 작은 정수 제외)에 메모리를 할당 한 다음 다시 해제해야합니다. – Duncan

1

파이썬리스트는 실제로는 몇 가지 일반적인 배열과 비슷하지만 리스프리스트가 아니지만 빠른 랜덤 액세스를 가지고 있습니다.

8

list들 (매우 C++의 std::vector는 말처럼) "역동적으로 성장 벡터"하지만 어떠한 방식으로 그 아래 그들에게 랜덤 액세스를 (그들은 목록을 연결하지 있어! -) 속도가 느려집니다. 목록 항목은 Python 객체 (항목)에 대한 참조입니다. 하나의 항목 만 액세스하면 (CPython에서) 항목의 참조 횟수가 증가합니다 (다른 구현에서는 고급 가비지 수집을 기반으로 할지라도 ;-). 배열의 항목은 원시 비트와 바이트입니다 : 하나에 액세스하려면 새로운 이진 값을 기반으로 새로운 Python 객체가 합성되어야합니다. 예 :

$ python -mtimeit -s'import array; c=array.array("B", "bzap")' 'c[2]' 
10000000 loops, best of 3: 0.0903 usec per loop 
$ python -mtimeit -s'c=list("bzap")' 'c[2]' 
10000000 loops, best of 3: 0.0601 usec per loop 

30 나노초의 액세스 시간이 너무 나쁘지는 않습니다 .-). 난 항상 사용자 지정 코드 모듈을 가져 오기 (사용 방법 등 반복의 자동 선택, 시간에 대해 표시 측정 단위 - 여담으로

timeit 명령 줄에서 사용하는 것이 훨씬 좋네요 있습니다 필요한 경우 호출 할 수있는 함수가 있지만 여기에는 그럴 필요가 없습니다) - 이므로을 모듈에서 가져 와서 사용하는 것보다 훨씬 편리합니다!

관련 문제