为什么比Python 3 * x**4.0
更快?x**4
Python 3 int
对象是成熟的对象,旨在支持任意大小。因此,它们是在C级别上进行处理的(请参阅如何在中将所有变量声明为PyLongObject *
type long_pow
)。这也使它们的取幂变得更加棘手和乏味,因为您需要ob_digit
使用它用来表示其值的数组进行操作。(勇敢的人士来了。-有关s的更多信息,请参见:了解Python中大整数的内存分配PyLongObject
。)
float
相反,可以将 Python 对象转换为C double
类型(通过使用PyFloat_AsDouble
),并且可以使用这些本机类型执行操作。这很棒,因为在检查了相关的边缘情况之后,它允许Python 使用平台的pow
(C 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
S作为Ç double
秒。
对于它的价值:Python 2.7.13
对我而言是一个2~3
更快的因子,并且显示出相反的行为。
先前的事实也解释了Python 2和3之间的差异,因此,我认为我也将解决此评论,因为它很有趣。
在Python 2中,您使用的旧int
对象与int
Python 3中的对象不同(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'>
s与<type 'int'>
s 相比是否比较慢,如果将x
名称包装long
在Python 2 中的调用中(实质上是强制将其long_pow
像在Python 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
生成相同的字节码'4 ** 4.'
,唯一的区别是LOAD_CONST
加载的是float 256.0
而不是int 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
所以时代是一样的。
*以上所有内容仅适用于CPython(Python的参考实现)。其他实现可能会有所不同。