나는 이것을 오랫동안 궁금해했다. 제목에서 알 수 있듯이 실제 기능이 더 빠르거나 단순히 절반의 힘을 올리는 것입니까?
최신 정보
이것은 조기 최적화 문제가 아닙니다. 이것은 단순히 기본 코드가 실제로 어떻게 작동하는지에 대한 질문입니다. 파이썬 코드의 작동 원리는 무엇입니까?
귀도 반 로섬 (Guido van Rossum)에게이 방법의 차이점을 알고 싶었던 이메일을 보냈습니다.
내 이메일:
파이썬에서 제곱근을 수행하는 방법은 적어도 3 가지가 있습니다 : math.sqrt, ‘**’연산자 및 pow (x, .5). 각 구현의 차이점이 궁금합니다. 효율성이 더 좋을 때?
그의 답변 :
pow와 **는 동일합니다. math.sqrt는 복소수에서는 작동하지 않으며 C sqrt () 함수에 연결됩니다. 어느 쪽이 더 빠른지 모르겠다.
답변
math.sqrt(x)
보다 훨씬 빠릅니다 x**0.5
.
import math
N = 1000000
%%timeit
for i in range(N):
z=i**.5
10 루프, 루프 당 3 : 156ms 최고
%%timeit
for i in range(N):
z=math.sqrt(i)
10 루프, 루프 당 3 : 91.1 ms
파이썬 3.6.9 사용하기 ( 노트북 ).
답변
- 최적화의 첫 번째 규칙 : 하지 마십시오
- 두 번째 규칙 : 아직 하지 마십시오
타이밍은 다음과 같습니다 (Python 2.5.2, Windows).
$ python -mtimeit -s"from math import sqrt; x = 123" "x**.5"
1000000 loops, best of 3: 0.445 usec per loop
$ python -mtimeit -s"from math import sqrt; x = 123" "sqrt(x)"
1000000 loops, best of 3: 0.574 usec per loop
$ python -mtimeit -s"import math; x = 123" "math.sqrt(x)"
1000000 loops, best of 3: 0.727 usec per loop
이 테스트는 x**.5
보다 약간 빠릅니다 sqrt(x)
.
파이썬 3.0의 경우 결과는 정반대입니다.
$ \Python30\python -mtimeit -s"from math import sqrt; x = 123" "x**.5"
1000000 loops, best of 3: 0.803 usec per loop
$ \Python30\python -mtimeit -s"from math import sqrt; x = 123" "sqrt(x)"
1000000 loops, best of 3: 0.695 usec per loop
$ \Python30\python -mtimeit -s"import math; x = 123" "math.sqrt(x)"
1000000 loops, best of 3: 0.761 usec per loop
math.sqrt(x)
항상보다 빠르다 x**.5
다른 컴퓨터 (Ubuntu, Python 2.6 및 3.1) .
$ python -mtimeit -s"from math import sqrt; x = 123" "x**.5"
10000000 loops, best of 3: 0.173 usec per loop
$ python -mtimeit -s"from math import sqrt; x = 123" "sqrt(x)"
10000000 loops, best of 3: 0.115 usec per loop
$ python -mtimeit -s"import math; x = 123" "math.sqrt(x)"
10000000 loops, best of 3: 0.158 usec per loop
$ python3.1 -mtimeit -s"from math import sqrt; x = 123" "x**.5"
10000000 loops, best of 3: 0.194 usec per loop
$ python3.1 -mtimeit -s"from math import sqrt; x = 123" "sqrt(x)"
10000000 loops, best of 3: 0.123 usec per loop
$ python3.1 -mtimeit -s"import math; x = 123" "math.sqrt(x)"
10000000 loops, best of 3: 0.157 usec per loop
답변
당신은 실제로 얼마나 많은 제곱근을 수행합니까? 파이썬으로 3D 그래픽 엔진을 작성하려고합니까? 그렇지 않다면 왜 읽기 쉬운 코드보다 암호가 많은 코드를 사용해야합니까? 시차는 내가 볼 수있는 거의 모든 응용 프로그램에서 누구나 알 수있는 것보다 적습니다. 나는 정말로 귀하의 질문을 내려 놓을 의도는 아니지만 조기 최적화로 너무 멀리 가고있는 것 같습니다.
답변
이러한 마이크로 벤치 마크에서는 수학 네임 스페이스에서 math.sqrt
검색하는 데 약간의 시간이 걸리기 때문에 속도가 느려집니다 sqrt
. 당신은 그것을 약간 향상시킬 수 있습니다
from math import sqrt
그럼에도 불구하고 timeit을 통해 몇 가지 변형을 실행하면 약간의 (4-5 %) 성능 이점이 있습니다. x**.5
흥미롭게도
import math
sqrt = math.sqrt
통계적으로 유의미한 속도로 속도 차이가 1 % 이내로 훨씬 더 빨라졌습니다.
Kibbee를 반복하고 이것이 아마도 조기 최적화라고 말할 것입니다.
답변
파이썬 2.6에서, (float).__pow__()
함수는 C에서 사용하는 pow()
함수와 math.sqrt()
함수는 C를 사용하여sqrt()
기능.
glibc 컴파일러에서 구현 pow(x,y)
은 매우 복잡하며 다양한 예외적 인 경우에 최적화되어 있습니다. 예를 들어 C pow(x,0.5)
를 호출하면 단순히 sqrt()
함수 를 호출합니다 .
사용의 속도 차이 .**
또는 math.sqrt
래퍼는 C 기능을 사용 주변 속도 강하게 최적화 플래그의 시스템에서 사용 / C 컴파일러에 의존하여 발생된다.
편집하다:
내 컴퓨터의 Claudiu 알고리즘 결과는 다음과 같습니다. 나는 다른 결과를 얻었다 :
zoltan@host:~$ python2.4 p.py
Took 0.173994 seconds
Took 0.158991 seconds
zoltan@host:~$ python2.5 p.py
Took 0.182321 seconds
Took 0.155394 seconds
zoltan@host:~$ python2.6 p.py
Took 0.166766 seconds
Took 0.097018 seconds
답변
가치가있는 것에 대해서는 (Jim의 답변 참조). 내 컴퓨터에서 python 2.5를 실행하십시오.
PS C:\> python -m timeit -n 100000 10000**.5
100000 loops, best of 3: 0.0543 usec per loop
PS C:\> python -m timeit -n 100000 -s "import math" math.sqrt(10000)
100000 loops, best of 3: 0.162 usec per loop
PS C:\> python -m timeit -n 100000 -s "from math import sqrt" sqrt(10000)
100000 loops, best of 3: 0.0541 usec per loop
답변
내 컴퓨터에서 “수학 가져 오기 sqrt”를 사용하더라도 Claudiu의 코드를 사용하면 x **. 5는 빠르지 만 psyco.full () sqrt (x)를 사용하면 적어도 200 % 더 빠릅니다.
