2012-06-22 1 views
19

, 나는 흥미로운 참조 : (연습) 만 STR 키를 다루는 것을 dicts에 대한 빠른 경로가 있음을Dict에서 문자열을 키로 사용하는 것이 항상 더 빠릅니까? 이 <a href="http://wiki.python.org/moin/TimeComplexity" rel="noreferrer">page</a>에

참고; 이는 알고리즘의 복잡성에는 영향을 미치지 않지만 일반적인 프로그램이 얼마나 빨리 완료되는지 등의 상수 요소에 큰 영향을 줄 수 있습니다.

그래서 정확히 무엇을 의미합니까?

문자열을 키로 사용할 때 항상 빠르다는 의미입니까?

예인 경우 그 이유는 무엇입니까?

업데이트 : 최적화에 대한 제안에 대한

감사합니다! 그러나 저는 실제로 최적화를해야하는지 또는 언제해야하는지보다 더 확실한 진실에 관심이 있습니다.

업데이트 2 :

덕분에 좋은 답변을, 여기 @DaveWebb에서 제공하는 link에서 콘텐츠 인용합니다 :

" ...

ma_lookup을 처음에는 lookdict_string 함수 (이름이 으로 변경되고 lookdict_unicode은 3.0으로 변경됨)로 설정됩니다. 사전에있는 키와 검색중인 키가 모두 표준 PyStringObject의 것입니다. 문자열 - 문자열 비교가 결코 예외를 발생시키지 않기 때문에 다양한 오류 검사를 완화하는 것과 같은 몇 가지 최적화를 할 수 있습니다. 또한 부자 오브젝트 비교가 필요하지 않으므로 PyObject_RichCompareBool을 호출하지 말고 항상 _PyString_Eq을 직접 사용하십시오.

... "또한

, 실험 번호를, 나는 결코 INT를 문자열로 변환하는이로

+2

나는이 모든 것이 핵심 객체의 '__hash__'메소드가 얼마나 빨리 발생하는지 추측 할 것이다. 나는 문자열을 해쉬하는 것이 상당히 간단하다고 생각하지만, 사전 조회의 어떤 부분이 해싱에 소비되는지 매우 흥미가있을 것이다. – Wilduck

+0

업데이트해도 아무런 변화가 없습니다. 아니요, 귀하의 키가 처음에는 문자열이 아닌 경우 대부분의 경우 더 빠르지 않을 것입니다. –

+0

@Lattyware 링크 된 페이지는 건설을위한 것뿐만 아니라 각 조회마다 속도가 증가하는 것을 의미합니다. – Wilduck

답변

17

Python dict의 기초가되는 C 코드는 String 키로 낙관됩니다. You can read about this here (그리고 블로그에서 언급 된 책에서).

dict에 문자열 키만 포함되어있는 경우 Python 런타임에서 문자열 비교가 발생하지 않는 오류를 처리하지 않고 비교 연산자를 무시하는 등의 작업을 수행 할 수 있습니다. 이렇게하면 문자열 키의 일반적인 경우가 조금 더 빠릅니다. dict. (업데이트 : 타이밍은 약간 이상을 보여줍니다.)

그러나 대부분의 Python 프로그램의 실행 시간을 크게 변경하지는 않습니다. dict 조회가 코드에서 병목 현상으로 측정되고 발견 된 경우에만이 최적화에 대해 걱정하십시오. As the famous quote says, "Premature optimization is the root of all evil."

유일한 방법은 훨씬 더 빨리 일이 정말 얼마나보고, 그들에게 시간이하는 것입니다

>>> timeit.timeit('a["500"]','a ={}\nfor i in range(1000): a[str(i)] = i') 
0.06659698486328125 
>>> timeit.timeit('a[500]','a ={}\nfor i in range(1000): a[i] = i') 
0.09005999565124512 

그래서 사용하여 문자열 키가 int 키에 비해 약 30 % 더 빠르게도, 그리고 내가 인정해야 차이의 크기에 놀랐습니다.

+0

당신의 테스트는''500''에 비해''500''을 얻는 데 드는 비용이 없다는 것을 전제로합니다. 이것은 큰 차이가 있습니다. 제 대답을보십시오. –

+1

질문은 문자열 키가 항상 빠르며 내 테스트가 표시되도록 의도되었는지 물어 보았습니다. 나는 다른 객체에서 문자열로 변환하고이를 키로 사용하는 것에 대해 묻는 질문은 아니라고 생각합니다. 여러 가지 이유 때문에 좋지 않을 것입니다. 그러나 선택이 가능할 때 문자열을 사용할 가치가 있다면 말입니다. –

+0

그건 그 맥락에서 벗어나고있어. 문자열 키를 사용하면 문자열 키를 사용하는 것이 속도가 느려지는 경우 문자열 키를 사용하는 것이 더 빠르다는 것을 알면 유용합니다. –

8

에만 영향을 미치는가없는 경우의 차이의 크기가 더 큰 것이라고 생각 일정 시간 동안은 전혀 문제가되지 않을 것입니다. 실제로 최적화해야하는 유일한 시간은 매우 큰 데이터 세트로 작업 할 때입니다.이 작업은 영향을주지 않습니다.

이것이 의미하는 바는 문자열을 키로 사용하는 작은 사전이있는 곳에서는 파이썬이 빠를 것입니다. 이것은 일반적인 사용법입니다. 그것은 최적화되었습니다.

이그나시오 바스케스 - 아브람 (Ignacio Vazquez-Abrams)이 지적했듯이, 키를 문자열로 변환하는 것은 사전에서 문자열로 얻는 약간의 향상보다 비용이 많이들 것입니다.

귀하의 상황과 관련이있는 짧은 용어를 사용하십시오. 최적화는 이전이 아닌 필요가있는 경우에만 수행해야합니다.

일부 테스트 : 문자열 기반 딕셔너리 빠른 동안

python -m timeit -s "a={key: 1 for key in range(1000)}" "a[500]" 
10000000 loops, best of 3: 0.0773 usec per loop 

python -m timeit -s "a={str(key): 1 for key in range(1000)}" "a[\"500\"]" 
10000000 loops, best of 3: 0.0452 usec per loop 

python -m timeit -s "a={str(key): 1 for key in range(1000)}" "a[str(500)]" 
1000000 loops, best of 3: 0.244 usec per loop 

당신이 볼 수 있듯이, 키를 변환하는 것은 완전히 (후 일부) 게인을 완화 비교하여 매우 비싸다.

그렇습니다. 사용하는 데이터가 인 경우 만 사전에 대한 키로 사용되며 저장소의 형식이 중요하지 않은 경우 작은 사전에 문자열을 입력하는 것이 좋습니다. 실제로 이것은 매우 드문 경우이며 이미 문자열을 사용하고있을 것입니다.

+4

특히 일부 유형을 문자열로 변환하는 것이 처음부터 키로 사용하는 것보다 비용이 많이들 수 있습니다. –

+0

미안하지만, 제 질문을 수정해야합니다. – xvatar

+0

@ IgnacioVazquez-Abrams 매우 그렇습니다. –

관련 문제