Jeśli spojrzeć na następujące czasy:int .__ mul__, wykonuje 2x wolniej niż operator.mul
C:\Users\Henry>python -m timeit -s "mul = int.__mul__" "reduce(mul,range(10000))"
1000 loops, best of 3: 908 usec per loop
C:\Users\Henry>python -m timeit -s "from operator import mul" "reduce(mul,range(10000))"
1000 loops, best of 3: 410 usec per loop
Istnieje znaczna różnica w szybkości wykonania między
reduce(int.__mul__,range(10000))
i reduce(mul,range(10000))
z czym te ostatnie są szybsze .
użyciu modułu dis
spojrzeć na to, co się dzieje:
Korzystanie int.__mul__
metody:
C:\Users\Henry>python
Python 2.7.4 (default, Apr 6 2013, 19:55:15) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> mul = int.__mul__
>>> def test():
... mul(1,2)
...
>>> import dis
>>> dis.dis(test)
2 0 LOAD_GLOBAL 0 (mul)
3 LOAD_CONST 1 (1)
6 LOAD_CONST 2 (2)
9 CALL_FUNCTION 2
12 POP_TOP
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
>>>
i operator mul
metodę
C:\Users\Henry>python
Python 2.7.4 (default, Apr 6 2013, 19:55:15) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from operator import mul
>>> def test():
... mul(1,2)
...
>>> import dis
>>> dis.dis(test)
2 0 LOAD_GLOBAL 0 (mul)
3 LOAD_CONST 1 (1)
6 LOAD_CONST 2 (2)
9 CALL_FUNCTION 2
12 POP_TOP
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
>>>
one wyglądają tak samo, więc dlaczego jest istnieje różnica w szybkości realizacji? Mam na myśli realizację CPython Pythona
To samo dzieje się na python3:
$ python3 -m timeit -s 'mul=int.__mul__;from functools import reduce' 'reduce(mul, range(10000))'
1000 loops, best of 3: 1.18 msec per loop
$ python3 -m timeit -s 'from operator import mul;from functools import reduce' 'reduce(mul, range(10000))'
1000 loops, best of 3: 643 usec per loop
$ python3 -m timeit -s 'mul=lambda x,y:x*y;from functools import reduce' 'reduce(mul, range(10000))'
1000 loops, best of 3: 1.26 msec per loop
Patrzysz na demontaż kodu bajtowego 'test()' i po prostu wywołuje 'mul', a więc jest taki sam w obu przypadkach. To dwie implementacje 'mul', które prawdopodobnie różnią się. –
@HristoIliev Dzięki, nie powiedziałem, że to był tylko test demontażu. Przypuszczam, że ma to dużo więcej sensu. Pójdę sprawdzić, jak te zostały wdrożone więcej niż wtedy. – HennyH
Czy używasz Pythona dwa? Problem może polegać na tym, że mulę int przepełni się i wywoła długi mul podczas gdy operator uniknie dodatkowych połączeń. – Bakuriu