首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么Python 3中x**4.0比x**4快?

为什么Python 3中x**4.0比x**4快?
EN

Stack Overflow用户
提问于 2017-02-21 06:15:14
回答 2查看 16.6K关注 0票数 164

为什么x**4.0x**4快?我使用的是CPython 3.5.2。

代码语言:javascript
复制
$ python -m timeit "for x in range(100):" " x**4.0"
  10000 loops, best of 3: 24.2 usec per loop

$ python -m timeit "for x in range(100):" " x**4"
  10000 loops, best of 3: 30.6 usec per loop

我试着改变我提升的幂,看看它是如何工作的,例如,如果我将x提升到10或16的幂,它会从30跳到35,但是如果我以浮点数的形式提升10.0,它只是在24.1~4附近移动。

我猜这与浮点数转换和2的幂有关,但我真的不知道。

我注意到,在这两种情况下,2的幂都更快,我猜是因为这些计算对于解释器/计算机来说更本机/更容易。但是,使用浮点时,它几乎不会移动。2.0 => 24.1~4 & 128.0 => 24.1~4 2 => 29 & 128 => 62

TigerhawkT3指出,这不会发生在循环之外。我检查了一下,这种情况只发生在(从我所看到的)基础被提升的时候。对此有什么想法吗?

EN

回答 2

Stack Overflow用户

发布于 2017-02-21 06:28:23

如果我们查看字节码,我们可以看到表达式是完全相同的。唯一的区别是作为BINARY_POWER参数的常量类型。所以可以肯定的是,这是由于int被转换成了浮点数。

代码语言:javascript
复制
>>> def func(n):
...    return n**4
... 
>>> def func1(n):
...    return n**4.0
... 
>>> from dis import dis
>>> dis(func)
  2           0 LOAD_FAST                0 (n)
              3 LOAD_CONST               1 (4)
              6 BINARY_POWER
              7 RETURN_VALUE
>>> dis(func1)
  2           0 LOAD_FAST                0 (n)
              3 LOAD_CONST               1 (4.0)
              6 BINARY_POWER
              7 RETURN_VALUE

更新:让我们看看CPython源代码中的Objects/abstract.c

代码语言:javascript
复制
PyObject *
PyNumber_Power(PyObject *v, PyObject *w, PyObject *z)
{
    return ternary_op(v, w, z, NB_SLOT(nb_power), "** or pow()");
}

PyNumber_Power调用ternary_op,它太长了,不能粘贴到这里,所以here's the link

它调用xnb_power槽,并将y作为参数传递。

最后,在float_pow()中,在Objects/floatobject.c的686行,我们看到参数在实际操作之前被转换为C double

代码语言:javascript
复制
static PyObject *
float_pow(PyObject *v, PyObject *w, PyObject *z)
{
    double iv, iw, ix;
    int negate_result = 0;

    if ((PyObject *)z != Py_None) {
        PyErr_SetString(PyExc_TypeError, "pow() 3rd argument not "
            "allowed unless all arguments are integers");
        return NULL;
    }

    CONVERT_TO_DOUBLE(v, iv);
    CONVERT_TO_DOUBLE(w, iw);
    ...
票数 25
EN

Stack Overflow用户

发布于 2017-09-11 13:18:12

因为一个是正确的,另一个是近似值。

代码语言:javascript
复制
>>> 334453647687345435634784453567231654765 ** 4.0
1.2512490121794596e+154
>>> 334453647687345435634784453567231654765 ** 4
125124901217945966595797084130108863452053981325370920366144
719991392270482919860036990488994139314813986665699000071678
41534843695972182197917378267300625
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42355194

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档