왜 x**4.0
빨리 보다는 x**4
파이썬 3 * ?
파이썬 3 int
객체는 임의의 크기를 지원하도록 설계된 본격적인 객체입니다. 그 사실 때문에 C 수준에서 그대로 처리됩니다 (모든 변수가 PyLongObject *
유형으로 선언되는 방법 참조 long_pow
). 이것은 또한 지수 훨씬 더하게 까다 하고 지루한을 당신이 함께 놀러 할 필요가 있기 때문에 ob_digit
그것을 수행하기 위해 그 값을 표현하기 위해 사용하는 배열입니다. ( 출처 용감한합니다. - 참조 : 파이썬에서 큰 정수에 대한 이해 메모리 할당 에 대한 자세한 내용은 PyLongObject
.들)
float
반대로 Python 객체는 (를 사용하여 ) C 유형 으로 변환 할 수 있으며 해당 기본 유형을 사용하여 작업을 수행 할 수 있습니다 . 이것은 대단한 관련 에지 경우에 확인 후, 그것은 파이썬을 허용하기 때문에 플랫폼 '를 사용 ( C의 입니다 ) 실제 지수를 처리하는 :double
PyFloat_AsDouble
pow
pow
/* Now iv and iw are finite, iw is nonzero, and iv is
* positive and not equal to 1.0. We finally allow
* the platform pow to step in and do the rest.
*/
errno = 0;
PyFPE_START_PROTECT("pow", return NULL)
ix = pow(iv, iw);
곳 iv
과 iw
우리의 원래있는 PyFloatObject
C 등의 double
의.
그만한 가치가있는 것은 : Python 2.7.13
for me는 2~3
더 빠르며 반대 행동을 보여줍니다.
이전의 사실 은 또한 파이썬 2와 3의 불일치를 설명 하므로 흥미 롭기 때문에이 의견도 다루겠다고 생각했습니다.
Python 2에서는 Python 3 int
의 int
객체 와 다른 오래된 객체를 사용하고 있습니다 ( int
3.x의 모든 객체는 PyLongObject
유형 임). Python 2에는 객체의 값에 따라 (또는 접미사를 사용하는 경우) 구별되는 것이 있습니다 L/l
.
# Python 2
type(30) # <type 'int'>
type(30L) # <type 'long'>
<type 'int'>
여기 참조는 같은 일을 수행 float
의 수행을 가 안전하게 C로 변환됩니다, long
지수가 그것을 수행 합니다 (이 int_pow
그렇게 할 수 있다면 그 때문에, 또한 레지스터에 그들을 넣어 컴파일러 힌트 수 차이를 만들) :
static PyObject *
int_pow(PyIntObject *v, PyIntObject *w, PyIntObject *z)
{
register long iv, iw, iz=0, ix, temp, prev;
/* Snipped for brevity */
이것은 좋은 속도 이득을 허용합니다.
방법 부진 보려면 <type 'long'>
비교에의 <type 'int'>
당신은, 랩 된 경우의 x
A의 이름 long
(기본적으로 사용하도록 강제 파이썬 2에서 전화를 long_pow
파이썬 3과), 속도 이득이 사라집니다 :
# <type 'int'>
(python2) ➜ python -m timeit "for x in range(1000):" " x**2"
10000 loops, best of 3: 116 usec per loop
# <type 'long'>
(python2) ➜ python -m timeit "for x in range(1000):" " long(x)**2"
100 loops, best of 3: 2.12 msec per loop
메모를 받아, 그 한 조각을 변환하는 비록 int
에 long
(@pydsinger가 가리키는 아웃과 같은) 다른 하나는하지 않지만,이 캐스트는 둔화 뒤에 기여 힘이 아니다. 의 구현입니다 long_pow
. (본문 만 long(x)
볼 시간 ).
[...] 루프 외부에서는 발생하지 않습니다. [...] 그것에 대한 아이디어가 있습니까?
이것은 CPython의 들여다 보는 구멍 최적화 프로그램으로 상수를 접습니다. 지수 결과를 찾기위한 실제 계산이없고 값만로드되므로 두 경우 모두 동일한 정확한 타이밍을 얻습니다.
dis.dis(compile('4 ** 4', '', 'exec'))
1 0 LOAD_CONST 2 (256)
3 POP_TOP
4 LOAD_CONST 1 (None)
7 RETURN_VALUE
동일한 바이트 코드는 int 대신 float 를 로드 '4 ** 4.'
한다는 점만 다릅니다 .LOAD_CONST
256.0
256
dis.dis(compile('4 ** 4.', '', 'exec'))
1 0 LOAD_CONST 3 (256.0)
2 POP_TOP
4 LOAD_CONST 2 (None)
6 RETURN_VALUE
따라서 시간은 동일합니다.
* 위의 모든 내용은 Python의 참조 구현 인 CPython에만 적용됩니다. 다른 구현은 다르게 수행 될 수 있습니다.