python - int.__mul__ , executes 2X slower than operator.mul -


if @ following timings:

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 

there significant difference in execution speed between

reduce(int.__mul__,range(10000)) , reduce(mul,range(10000)) latter being faster.

using dis module @ happening:

using int.__mul__ method:

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" 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 >>> 

and operator mul method

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" more information. >>> 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 >>> 

they appear same, why there difference in execution speed? referring cpython implementation of python


the same happens on 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 

int.__mul__ slot wrapper, namely, pywrapperdescrobject, while operator.mul buit-in function. think opposite execution speed caused difference.

>>> int.__mul__ <slot wrapper '__mul__' of 'int' objects> >>> operator.mul <built-in function mul> 

when call pywrapperdescrobject, wrapperdescr_call called.

 static pyobject * wrapperdescr_call(pywrapperdescrobject *descr, pyobject *args, pyobject *kwds) {     py_ssize_t argc;     pyobject *self, *func, *result;      /* make sure first argument acceptable 'self' */     assert(pytuple_check(args));     argc = pytuple_get_size(args);     if (argc d_type->tp_name);         return null;     }     self = pytuple_get_item(args, 0);     if (!_pyobject_realissubclass((pyobject *)py_type(self),                                   (pyobject *)(descr->d_type))) {         pyerr_format(pyexc_typeerror,                      "descriptor '%.200s' "                      "requires '%.100s' object "                      "but received '%.100s'",                      descr_name((pydescrobject *)descr),                      descr->d_type->tp_name,                      self->ob_type->tp_name);         return null;     }      func = pywrapper_new((pyobject *)descr, self);     if (func == null)         return null;     args = pytuple_getslice(args, 1, argc);     if (args == null) {         py_decref(func);         return null;     }     result = pyeval_callobjectwithkeywords(func, args, kwds);     py_decref(args);     py_decref(func);     return result; } 

let @ found!

func = pywrapper_new((pyobject *)descr, self); 

a new pywrapper object has been constructed. slow down execution speed significantly. sometimes, takes more time create new object run simple function.
thus, not surprised int.__mul__ slower operator.mul.


Comments

Popular posts from this blog

SPSS keyboard combination alters encoding -

Add new record to the table by click on the button in Microsoft Access -

javascript - jQuery .height() return 0 when visible but non-0 when hidden -