2009-12-24 4 views
3

, 나는 어떤을 파이썬에서 더 비싼했다 궁금하면? 두 번째 줄의 줄 수는 줄었지만 재 할당이 조건 전환보다 비용이 많이 드는 지 궁금합니다.파이썬 코드의 최적화를 숙고에서 다른 마이크로 최적화

+10

timeit과 비교할 때 무엇을 배웠습니까? timeit을 실행하지 않고 최적화에 대해 묻지 마십시오. –

+0

고마움, 나는 시간을 인식하지 못하고 방금 그것을 발견하고 시간 테스트를하고있다. –

+1

-1 for speculative micro-optimization –

답변

20

, 궁금하지 않습니다 측정을 깊이 생각하지 마십시오 - 쉘에서 timeit로 명령 행 (지금까지는 그것을 사용하는 가장 좋은, 가장 간단한 방법!). 노트북에 맥 OSX 10.5 파이썬 2.5.4 ... :

$ python -mtimeit -s'x=0' 'if x: d=1' 'else: d=2' 
10000000 loops, best of 3: 0.0748 usec per loop 
$ python -mtimeit -s'x=1' 'if x: d=1' 'else: d=2' 
10000000 loops, best of 3: 0.0685 usec per loop 
$ python -mtimeit -s'x=0' 'd=2' 'if x: d=1' 
10000000 loops, best of 3: 0.0734 usec per loop 
$ python -mtimeit -s'x=1' 'd=2' 'if x: d=1' 
10000000 loops, best of 3: 0.101 usec per loop 

그래서 당신이 볼 : x가 거짓이지만, 경우 1.4 나노초을 절약 할 수 있습니다 형태가 40.2 나노초 비용 (가) "경우 단지 -"X에 해당하는 경우 "if/else"형식과 비교할 때; 따라서 마이크로 최적화 환경에서 x가 true 또는 false보다 false 일 확률이 30 배 이상인 경우에만 전자를 사용해야합니다. 또한 :

$ python -mtimeit -s'x=0' 'd=1 if x else 2' 
10000000 loops, best of 3: 0.0736 usec per loop 
$ python -mtimeit -s'x=1' 'd=1 if x else 2' 
10000000 loops, best of 3: 0.076 usec per loop 

... if/else의 삼항 연산자에는 자체적으로 약간의 +와 - 빼기가 있습니다.

차이가 이보다 작은 경우 반복해서 측정하고 노이즈 수준을 확인하고 "노이즈"의 차이를 중요하게 생각하지 않도록해야합니다.

$ python -mtimeit -s'x=1' 'd=1 if x else 2' 
10000000 loops, best of 3: 0.076 usec per loop 
$ python -mtimeit -s'x=1' 'd=1 if x else 2' 
10000000 loops, best of 3: 0.0749 usec per loop 
$ python -mtimeit -s'x=1' 'd=1 if x else 2' 
10000000 loops, best of 3: 0.0742 usec per loop 
$ python -mtimeit -s'x=1' 'd=1 if x else 2' 
10000000 loops, best of 3: 0.0749 usec per loop 
$ python -mtimeit -s'x=1' 'd=1 if x else 2' 
10000000 loops, best of 3: 0.0745 usec per loop 

지금 당신이 표현 양식이 시스템에서 (소요 및 키의 버전 것을 주장 할 수 있습니다 : 예를 들어,의/다른 경우 "x는 사실은"만일 표현 대 문을 비교 각각 몇 번 반복 소프트웨어) 74.2에서 76.0 나노초 - 단일 숫자보다 표현 범위가 훨씬 넓습니다. 그리고 유사 지금

$ python -mtimeit -s'x=1' 'if x: d=1' 'else: d=2' 
10000000 loops, best of 3: 0.0688 usec per loop 
$ python -mtimeit -s'x=1' 'if x: d=1' 'else: d=2' 
10000000 loops, best of 3: 0.0681 usec per loop 
$ python -mtimeit -s'x=1' 'if x: d=1' 'else: d=2' 
10000000 loops, best of 3: 0.0687 usec per loop 
$ python -mtimeit -s'x=1' 'if x: d=1' 'else: d=2' 
10000000 loops, best of 3: 0.0679 usec per loop 
$ python -mtimeit -s'x=1' 'if x: d=1' 'else: d=2' 
10000000 loops, best of 3: 0.0692 usec per loop 

당신은 문 양식이 67.9 69.2 나노초 (동일 조건) 소요 자신있게 명시 할 수 있습니다 그래서 x의 진실성, 즉 표현 양식의 장점은 4.8에서 8.1 나노초입니다. (이 후자의 간격을 6.3에서 6.8 나노초로 제한하는 것은 상당히 공정합니다. min/min과 max/max 대신 min/max 및 max/min보다 넓고, 더 건전한 추정치).

이러한 미세한 차이에 얼마나 많은 시간과 노력을 기울여야하는지에 대해 알게되면 이 미세한입니다. 물론 다른 문제입니다.

+3

구조에 SuperMartelli! 거대한 벤치 마크 블록에 대해서는 +1. –

+1

나는 사람들이해야 할 일에 대해 사람들에게 강연하면서 더 많은 즐거움을 얻는 것처럼 보이지만, 다른 사람들은 더 미세한 점에 관해 우리를 교육함으로써 더 많은 즐거움을 얻습니다. 고마워, 알렉스. –

2

두 번째 것은 분명히 더 비쌉니다. x이 거짓이면 동일한 작업을 수행하고 x이 참일 경우 두 번 할당합니다.

가정 : 조건부 점프보다 파이썬에서 할당이 더 비쌉니다. 조건부 점프는 해석 이후 의미가 있으며 런타임 해시를 읽은 다음 새 값을 가져와 동일한 해시로 업로드해야합니다.

+1

파이썬을 완전히 무시할 수 있다고 생각합니다. 할당은 베어 메어 코드에서도 조건부 점프보다 느릴 수 있습니다. 비교 함수가 실제로 불쾌한 경우가 아니라면 (분명 직선 수의 경우는 제외), 테스트 된 조건이 모두 합리적인 기회가 있다고 가정 할 때 첫 번째 형식은 거의 항상 우수한 것으로 평균화되어야합니다. –

+2

조건부 점프로 인해 캐시 삭제가 발생하면 보이는 것처럼 곧장 앞으로 나아 가지 않습니다. 그러나 Python의 경우 특별히 좋은 선택입니다. – Blindy

+0

@Nicholas : asm에서 레지스터에 맞는 32 비트 정수와 같은 작은 객체의 경우 할당은 가능한 가장 저렴한 연산입니다. x86에서'mov reg, imm32' 또는 특히'mov reg, reg'는 매우 저렴합니다. 현대 AMD (불도저 가족) 또는 인텔 (SnB 가족)에 두번째 사람은 [실행 단위를 필요로하지 않는다] (http://agner.org/optimize/). 조건부 브랜치 ('cmp' /'jcc')는 정확하게 예측할 때 상당히 저렴하지만, 여전히 취해진 경우는 명령 페치에 영향을 미친다. 잘못된 예측은 50 배의 'mov'비용입니다. 'mov [mem], reg'는 조건부 브랜치보다 저렴합니다. –

5

당신은 아마 벤치 마크이해야하지만, 삼항 연산자를 사용하여 세 번째 형태도있다 :

d = 1 if x else 2 
+2

'd = 2 - bool (x)' –

+0

은 1 대 2의 경우에만 작동하며, 15와 31을 원한다면 작동하지 않습니다. –

+2

Ewww, Chris, 문자 그대로 나를 아프게했다. : –

1

나는 가장 읽을 수있는 것이 가장 최적화되어 있다고 주장한다.

if ... else 구문을 사용하면 두 가지 경우 중 하나를 다루는 것이 분명해집니다.

(d == 2)가 일반적인 값이고 if가 비정상적인 경우를 테스트하는 경우 할당 구조가 더 이해할 수 있습니다. 할당이 if에서 멀리 이동하면이 구문은 명확하지 않게됩니다.

이 간단한 예제에서는 별 문제가 없습니다. 좀 더 복잡한 코드의 경우 CPU 사이클을 약간 줄이더라도 가독성을 위해 항상 최적화 할 것입니다.

+0

파이썬의 주요 철학 중 하나는 "코드는 한 번 작성되지만 여러 번 읽습니다"입니다. 이와 같이 엄청나게 단순한 최적화를 고려하기 시작하면 모듈의 해당 부분을 C 확장으로 다시 작성하고 Python 코드를 멋지고 읽기 쉽게 유지하는 것이 훨씬 나을 것입니다. '2-bool (x)'는 1.2 나노초 더 빠르지 만'if x : d = 1'보다 훨씬 덜 분명하고'if (x) {d = 1; – dbr