gpt4 book ai didi

python - int.__mul__ ,执行速度比 operator.mul 慢 2 倍

转载 作者:太空狗 更新时间:2023-10-29 17:18:18 25 4
gpt4 key购买 nike

如果您查看以下时间:

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

两者执行速度有显着差异

reduce(int.__mul__,range(10000))reduce(mul,range(10000)) 后者更快。

使用 dis 模块查看发生了什么:

使用 int.__mul__ 方法:

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

和运算符mul方法

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

它们看起来一样,那么执行速度为什么会有差异呢?我指的是 Python 的 CPython 实现


在 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__是一个插槽包装器,即 PyWrapperDescrObject , 而 operator.mul是一个内置函数。我认为相反的执行速度是由这种差异造成的。

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

当我们调用 PyWrapperDescrObject , wrapperdescr_call被称为。


static PyObject *
wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
{
Py_ssize_t argc;
PyObject *self, *func, *result;

/* Make sure that the first argument is acceptable as '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 a '%.100s' object "
"but received a '%.100s'",
descr_name((PyDescrObject *)descr),
descr->d_type->tp_name,
self->ob_type->tp_name);
return NULL;
}

<b>func = PyWrapper_New((PyObject *)descr, self);</b>
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;
}

让我们看看我们发现了什么!

func = PyWrapper_New((PyObject *)descr, self);

一个新的 PyWrapper 对象已经构建完成。它会显着降低执行速度。有时,创建一个新对象比运行一个简单的函数需要更多的时间。
因此,int.__mul__operator.mul 慢也就不足为奇了。

关于python - int.__mul__ ,执行速度比 operator.mul 慢 2 倍,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16633424/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com