2009-07-16 181 views
37

我遇到了關於字典內存管理的this question,裏面提到了實習生的功能。它究竟做了什麼,什麼時候使用它?python sys.intern做什麼,它應該在什麼時候使用?

舉個例子:

如果我有一組稱爲看出,包含在表格元組(字符串1,字符串),我使用來檢查重複,將存儲(實習生(字符串1) ,intern(string2))提高了性能記憶還是速度?

回答

47

Python 3文檔

sys.intern(string) 

在「實習」的字符串表中輸入字符串,返回 實習字符串 - 這是字符串本身或複印件。實際字符串 對於在字典查找中獲得一些性能很有用 - 如果字典中的 鍵被禁用,並且查找鍵被禁用,則可以通過指針比較 而不是字符串比較。正常情況下,Python 程序中使用的名稱會自動被攔截,並且用於保存模塊,類或實例屬性的字典具有實名密鑰。

Interned字符串不是不朽的;您必須保留對intern()的返回值的引用,以從中受益。

澄清

作爲文檔建議,該sys.intern功能旨在被用於性能優化

sys.intern函數維護一個表實例字符串。當您嘗試實習生字符串,則函數查找它的表:

  1. 如果字符串不存在(尚未拘留)的功能可保存 它在表上,並返回它來自interned strings表。

    >>> import sys 
    >>> a = sys.intern('why do pangolins dream of quiche') 
    >>> a 
    'why do pangolins dream of quiche' 
    

    在上面的例子中,a保存了interned字符串。即使它不可見,sys.intern函數已將字符串對象'why do pangolins dream of quiche'保存在interned strings表中。

  2. 如果該字符串存在(已被攔截),該函數將從 interned strings表中返回該字符串。

    >>> b = sys.intern('why do pangolins dream of quiche') 
    >>> b 
    'why do pangolins dream of quiche' 
    

    即使它不是立即可見,因爲字符串'why do pangolins dream of quiche'之前已被拘留,b現在擁有相同的字符串對象a

    >>> b is a 
    True 
    

    如果我們創建不使用實習生相同的字符串,我們最終得到的是具有相同值的兩個不同的字符串對象。

    >>> c = 'why do pangolins dream of quiche' 
    >>> c is a 
    False 
    >>> c is b 
    False 
    

使用sys.intern你確保你永遠不會創建具有相同的價值,當你請求第二個字符串對象的創建具有相同值作爲現有字符串對象,您會收到兩個String對象對預先存在的字符串對象的引用。這樣,你就是節省內存。此外,字符串對象現在比較現在是非常有效,因爲它是通過比較兩個字符串對象的內存地址而不是它們的內容來執行的。

+0

如果我們寫的`.py`文件中的代碼並做到這一點,我們得到'C是作爲了` TRUE;。這是爲什麼? – 2018-02-07 04:46:54

4

它返回字符串的規範實例。

因此,如果您有許多字符串實例相同,則可以節省內存,此外,還可以通過身份比較規範化字符串,而不是相等,速度更快。

17

本質上,實習生在一個實習字符串集合中查找(或存儲,如果不存在)字符串,因此所有實習實例將共享相同的身份。您交換查找此字符串的一次性成本以進行更快速的比較(比較可以在僅檢查身份後返回True,而不必比較每個字符),並減少內存使用量。

但是,python將automatically intern strings that are small, or look like identifiers,所以你可能會發現你沒有得到任何改善,因爲你的字符串已經在幕後實施。例如:

>>> a = 'abc'; b = 'abc' 
>>> a is b 
True 

過去,一個缺點是實習字符串是永久性的。一旦被攔截,即使所有引用都被刪除,字符串內存也不會被釋放。我認爲這不再是更新版本的Python的情況。

+1

* CPython *會自動插入很小的字符串 - 這是一種實現行爲,並不保證所有實現都是真實的(但可能是)。 – gsnedders 2015-04-15 16:10:47

相關問題