Python int函数性能

时间:2014-02-23 09:30:33

标签: python python-3.x int python-internals

Python的内置函数int是否仍会尝试转换提交的值,即使该值已经是整数?

更简洁:转换算法导致int('42')int(42)之间有任何性能差异吗?

4 个答案:

答案 0 :(得分:10)

这在函数long_long in Objects/longobject.c中处理,详见thefourtheye:

static PyObject *
long_long(PyObject *v)
{
    if (PyLong_CheckExact(v))
        Py_INCREF(v);
    else
        v = _PyLong_Copy((PyLongObject *)v);
    return v;
}

因此,当参数已经是int时,引用计数会递增并返回相同的对象。

一般来说,您可以为不可变类型假设类似的行为。例如,tuple(mytuple)会返回对mytuple的新引用,相反,list(mylist)会创建mylist的副本。

答案 1 :(得分:6)

如果将int对象传递给int(),则会得到相同的对象(CPython 3.3.2):

>>> a = 1000 * 1000 # large enough to avoid interning
>>> b = int(a)
>>> a is b
True

我不知道“算法性能差异”是什么意思,但它不会创建新对象。

答案 2 :(得分:5)

根据comments in the source code

  

将数字或字符串转换为整数,如果没有参数则返回0   给出。如果x是数字,则返回x.__int__()。对于浮点   数字,这会截断为零。

     

如果x不是数字或者给出了base,那么x必须是一个字符串,   bytes或bytearray实例,表示中的整数文字   给定基数

因此,如果输入是一个数字,将在该对象上调用__int__函数,并返回结果。内部nb_int is an item in PyNumberMethods structure,对应__int__函数。根据撰写本文时的最新源代码long_long is the function which corresponds to the nb_int function,其定义如下

long_long(PyObject *v)
{
    if (PyLong_CheckExact(v))
        Py_INCREF(v);
    else
        v = _PyLong_Copy((PyLongObject *)v);
    return v;
}

这里PyLong_checkExact是一个宏,它只检查当前对象是否真的是long类型。如果是真的,它只是增加引用计数并按原样返回对象,不会做任何额外的事情。

如果输入是字符串形式,则必须将字符串转换为具有PyLong_FromUnicodeObject函数的数字。

答案 3 :(得分:1)

为什么不直接比较两者?

>>> def f(): int('42')
... 
>>> def g(): int(42)
... 
>>> from timeit import timeit
>>> timeit(f)
0.3384080480027478
>>> timeit(g)
0.2566616949989111