2014-02-23 63 views
7

Python的內置函數int是否仍嘗試轉換提交的值,即使該值已經是整數?Python的int函數性能

更簡潔:轉換算法引起的int('42')int(42)之間是否有任何性能差異?

+0

'int'實際上是一個沒有引號的字符串。該轉換在編譯期間完成(即在源代碼的第一次處理期間)。 Python的'int'對象必須在兩種情況下構造。由於Python不使用機器「int」,所以在兩種情況下複雜性都應該相似。 – pepr

回答

5

作爲每comments in the source code

轉換一個數字或字符串的整數,或者,如果沒有給出參數 返回0。如果x是數字,則返回x.__int__()。對於浮點數 ,這會向零截斷。

如果x不是數字或如果基給出,則x必須是一個字符串, 字節或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功能。

1

你爲什麼不比較兩者?

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

@Crystal這將取決於你正在使用或您的最終用戶將使用實施。 – Hyperboreus

6

如果你傳遞一個int對象int(),你會得到相同的對象返回(CPython的3.3.2):

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

我不知道你所說的「算法的性能差異」是什麼意思,但它不會創建一個新對象。

+0

不需要道歉,這是更好的答案 – jonrsharpe

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的副本。

+0

雖然這幾乎與實際功能相似,但實際上這是一個內部幫助功能。 – thefourtheye

+0

@thefourtheye你是對的,編輯。 –