Python的int函数性能

vau*_*tah 7 python int python-3.x python-internals

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

更简洁:是否有任何之间的性能差异int('42'),并int(42)通过转换算法造成的?

Jan*_*ila 10

这是在函数long_longObjects/longobject.c处理的,正如thefourtheye更详细地解释的那样:

static PyObject *
long_long(PyObject *v)
{
    if (PyLong_CheckExact(v))
        Py_INCREF(v);
    else
        v = _PyLong_Copy((PyLongObject *)v);
    return v;
}
Run Code Online (Sandbox Code Playgroud)

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

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


jon*_*rpe 6

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

>>> a = 1000 * 1000 # large enough to avoid interning
>>> b = int(a)
>>> a is b
True
Run Code Online (Sandbox Code Playgroud)

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


the*_*eye 5

根据源代码中注释,

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

如果x不是数字或者给定了base,则x必须是字符串,字节或bytearray实例,表示给定基数中的整数字面值

因此,如果输入是一个数字,__int__将在该对象上调用函数,并返回结果.内部nb_int是PyNumberMethods结构中的一个项目,它对应于该__int__函数.根据撰写本文时的最新源代码,long_long该函数对应于nb_int函数,该函数定义如下

long_long(PyObject *v)
{
    if (PyLong_CheckExact(v))
        Py_INCREF(v);
    else
        v = _PyLong_Copy((PyLongObject *)v);
    return v;
}
Run Code Online (Sandbox Code Playgroud)

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

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