一文掌握Python 的字符串駐留是如何工作的

2025年01月17日06:32:25 科技 1309

一文掌握Python 的字符串駐留是如何工作的 - 天天要聞

Python 是一種靈活的編程語言,它提供了各種機制來優化性能和內存使用情況。其中一種優化技術就是字符串駐留。

字符串駐留

字符串駐留是一個根植於內存和性能優化的概念,尤其是在 Python 等編程語言中。

什麼是字符串駐留?

字符串駐留的核心是只存儲每個不同不可變字符串值的一個副本。不可變字符串一旦創建就無法更改。這種不變性是駐留過程的關鍵,因為它確保存儲的字符串值保持不變,從而允許多個引用安全地指向同一內存位置。

當一個字符串被駐留時,任何其他具有相同值的字符串都將引用相同的內存位置。這意味着 Python 不會為相同的字符串創建新的內存分配,而是重用現有的內存分配。這種重用使字符串駐留成為一種有效的優化技術。

為什麼字符串駐留很有用?

字符串駐留有幾個顯著的好處:

  1. 內存效率:通過僅存儲相同字符串的一個副本,Python 減少了使用的內存量。這對於處理大量重複字符串值的應用程序(例如文本處理、數據解析和日誌系統)尤其有益。
  2. 性能改進:駐留字符串可以加快比較速度。通常,比較兩個字符串需要逐個檢查每個字符,這對於長字符串來說可能非常耗時。但是,如果字符串被駐留,Python 可以簡單地比較它們的內存地址。如果地址相同,則字符串相等。這種指針比較比逐個字符比較快得多。
  3. 一致性和安全性:字符串駐留有助於保持一致性,並避免因擁有同一字符串的多個副本而可能出現的潛在錯誤。由於駐留字符串是不可變的且存儲在單個位置,因此無意中修改一個字符串(如果字符串是可變的)不會影響其他字符串,從而確保數據完整性。

何時應使用字符串駐留?

了解字符串駐留有益的場景可以幫助您做出明智的決定,確定何時在代碼中使用它:

  1. 重複字符串的高頻率:如果您的應用程序涉及處理大量重複字符串,則駐留可以顯著節省內存並提高性能。
  2. 性能關鍵的字符串比較:在字符串比較是性能瓶頸的情況下,實習可以通過利用指針相等性檢查而不是逐個字符的比較來加快比較速度。
  3. 資源受限的環境:在內存受限的環境中,例如嵌入式系統或在有限硬件上運行的應用程序,駐留可以幫助優化內存使用情況。

限制和注意事項

雖然字符串駐留提供了明顯的好處,但重要的是要注意它的局限性:

  • 內存開銷:駐留需要在內存節省和管理駐留字符串池的開銷之間進行權衡。駐留過多的字符串(尤其是較大的字符串)可能會導致駐留字符串池本身的內存使用量增加。
  • 垃圾回收:只要引用了 Interned 字符串,它們通常就不會被垃圾回收。如果 Interned 字符串使用不當,則可能會導致內存泄漏
  • 並非總是自動:Python 不會自動駐留所有字符串。了解何時手動駐留字符串對於實現所需的性能和內存優勢至關重要。

Python 中的字符串駐留是如何工作的

Python 的字符串駐留機制在優化內存使用和提高性能方面起着至關重要的作用。了解 Python 中字符串駐留的工作原理需要探索自動和手動駐留過程,並識別發生駐留的具體場景。

自動駐留

Python 會自動保留某些字符串以優化內存使用和性能。此過程是隱式的,通常涉及類似於標 識符且經常重複使用的字符串。

標識符的駐留

Python 中的標識符(例如變量名和函數名)會自動保留。這些標識符通常由字母數字字符和下劃線組成。Python 之所以保留這些字符串,是因為它們在程序執行過程中被廣泛使用且經常被比較。

示例:標識符的自動駐留

a = 'name'
 b = 'name' 
print (a is b)   # 輸出:True

 x = 'variable_1'
 y = 'variable_1' 
print (x is y)   # 輸出:True

在此示例中,字符串'name''variable_1'由 Python 自動駐留。因此,ab引用相同的內存位置,與x和一樣y

短字符串

Python 還會駐留短字符串,通常是長度少於 20 個字符的字符串。這些短字符串通常會在程序中重複使用,駐留它們可以顯著減少內存使用量。

示例:自動駐留短字符串

a = 'short'
 b = 'short' 
print (a is b)   # 輸出: True

 m = 'longer_string_that_is_not_interned'
 n = 'longer_string_that_is_not_interned' 
print (m is n)   # 輸出: False

在此示例中,短字符串'short'會自動駐留,因此ab引用相同的內存位置。但是,較長的字符串'

longer_string_that_is_not_interned'
不會自動駐留,因此mn引用不同的內存位置。

手動駐留

對於未自動駐留的字符串,Python 提供了一種使用模塊sys.intern()中的函數手動駐留它們的機制sys。當處理較大的字符串或不符合自動駐留標準的字符串時,這很有用。

使用sys.intern()

sys.intern()函數確保相同的字符串共享相同的內存位置,即使它們沒有被 Python 自動駐留。

示例:手動駐留sys.intern()

import sys

a = 'unique_string'
 b = 'unique_string' 
print (a is b)   # 輸出:False

 a = sys.intern( 'unique_string' ) 
b = sys.intern( 'unique_string' ) 
print (a is b)   # 輸出:True

在此示例中,字符串'unique_string'不會自動駐留,因此ab最初引用不同的內存位置。使用之後sys.intern()a和都b引用相同的內存位置,這表明字符串已被手動駐留。

編譯期間駐留

Python 還會在編譯過程中駐留字符串,尤其是那些出現在函數定義和類定義中的字符串。這意味着在編譯時創建的字符串通常會被駐留以優化內存使用並提高性能。

示例:編譯時字符串駐留

defgreet ():return'hello'a = greet()b= 'hello'print ( a is b)   #輸出:True
     



在此示例中,字符串'hello'在函數編譯期間被駐留greet。因此,a和都b引用相同的內存位置。

字符串駐留的含義

字符串駐留會對內存使用和性能產生重大影響。通過了解 Python 何時以及如何駐留字符串,開發人員可以編寫更高效、更優化的代碼。

內存使用情況

通過確保相同的字符串僅存儲一次,駐留字符串可以減少程序的總體內存佔用。這對於處理大量重複字符串值的應用程序尤其有益。

示例:通過 Interning 節省內存

import sys 

str_list = [sys.intern( 'repeat' ) for _ in  range ( 1000 )] 
print (str_list[ 0 ] is str_list[ 999 ])   # 輸出:True

在此示例中,使用sys.intern()確保字符串的所有 1000 個實例都'repeat'引用相同的內存位置,從而節省大量內存。

性能改進

內置字符串允許更快的比較,因為它們啟用了指針相等性檢查,而不是逐個字符的比較。這可以在字符串比較是關鍵操作的應用程序中帶來明顯的性能提升。

示例:使用 Interning 進行更快的字符串比較

a = sys.intern( 'compare_me' ) 
b = sys.intern( 'compare_me' ) 

if a is b: 
    print ( '字符串相同(快速比較)' ) 
else : 
    print ( '字符串不相同' )

a在這個例子中,和之間的比較b很快,因為它涉及檢查它們的內存地址。如果字符串沒有被駐留,比較將涉及檢查每個字符,這會更慢。

字符串駐留髮生的場景

Python 中的字符串駐留並不總是可預測的,但在某些情況下它經常發生。識別這些場景可以幫助您有效利用字符串駐留來優化內存使用和性能。

短字符串和標識符

Python 默認會保留短字符串和標識符。標識符是可用作變量名的字符串,例如字母數字字符串和下劃線。短字符串(通常少於 20 個字符)也會自動保留。

示例:Interned 標識符

a = 'name'
 b = 'name' 
print (a is b)   # 輸出:True

 x = 'name_1'
 y = 'name_1' 
print (x is y)   # 輸出:True

在這些示例中,字符串namename_1被保留,因為它們看起來像標識符,並且由字母數字字符和下劃線組成。因此,ab引用相同的內存位置,就像x和 一樣y

編譯時創建的字符串

在編譯時創建的字符串(例如函數定義中使用的字符串)通常會被駐留。這是因為 Python 將源代碼編譯為位元組碼,在此過程中,某些字符串會被駐留以優化內存使用並提高性能。

示例:編譯時字符串

defgreet ():return'hello'a = greet()b= 'hello'print ( a is b)   #輸出:True
     



hello在此示例中,函數返回的字符串greet在函數編譯期間被駐留。因此,a和都b引用相同的內存位置。

明確駐留sys.intern()

對於未自動駐留的字符串,您可以使用該sys.intern()方法顯式地駐留它們。這對於較長或不符合自動駐留標準但仍在程序中頻繁使用或比較的字符串特別有用。

示例:顯式駐留

導入系統

a = '唯一字符串'
 b = '唯一字符串' 
print (a is b)   # 輸出:False

 a = sys.intern( '唯一字符串' ) 
b = sys.intern( '唯一字符串' ) 
print (a is b)   # 輸出:True

在此示例中,字符串unique string不會自動駐留,因此ab最初引用不同的內存位置。使用之後sys.intern()a和都b引用相同的內存位置,這表明字符串已被手動駐留。

大量字符串

在應用程序處理大量字符串的場景中(例如處理文本數據、解析文件或處理大型數據集),字符串駐留可以顯著節省內存並提高性能。通過駐留重複的字符串,您可以減少總體內存佔用並加快字符串比較操作的速度。

import sys 

words = [ 'interned_word' ] * 1000
 interned_words = [sys.intern(word) for word in words] 

print (interned_words[ 0 ] is interned_words[ 999 ])   # 輸出:True

在此示例中,列表words包含 1000 個字符串實例interned_word。通過使用sys.intern(),字符串的所有實例都將被保留,從而節省大量內存。因此,列表的第一個和最後一個元素interned_words引用相同的內存位置。

緩存和記憶

緩存和記憶技術通常涉及存儲昂貴的函數調用的結果以避免冗餘計算。在這些情況下,字符串駐留可以減少內存使用量並加快緩存字符串的比較速度,從而大有裨益。

示例:使用 Interned 字符串進行緩存

導入系統

緩存 = {} 

def  expensive_function(param):
    param = sys.intern(param)
    如果緩存中的參數:
        返回緩存[param]
    結果= compute_expensive_result(param)
    緩存[param] = result
    返回結果

在此示例中,在檢查緩存之前,expensive_function先實習字符串。這可確保相同的字符串引用相同的內存位置,從而使緩存查找更加高效。param

性能關鍵型應用程序

在性能至關重要的應用程序中,例如那些需要頻繁進行字符串比較或在內存受限的環境中運行的應用程序,字符串駐留可以帶來巨大的好處。通過駐留字符串,您可以優化內存使用率和字符串操作的速度。

示例:性能關鍵型字符串比較

導入系統

a = sys.intern( 'performance' ) 
b = sys.intern( 'performance' )

如果a是b:
    print ( '字符串相同(快速比較)' ) 
else:
    print ( '字符串不相同' )

a在這個例子中,和之間的比較b很快,因為它涉及檢查它們的內存地址。如果字符串沒有被駐留,比較將涉及檢查每個字符,這會更慢。

結論

Python 中的字符串駐留是一種強大的優化技術,通過僅存儲相同的不可變字符串的一個副本來提高內存效率和性能。通過自動駐留標識符和短字符串,Python 可以節省內存並加快字符串比較速度。sys.intern()對於不適用自動駐留的場景,開發人員還可以使用該函數手動駐留字符串。

了解字符串駐留髮生的方式和時間可以幫助您做出明智的決策來優化 Python 代碼,尤其是在處理大量字符串、性能關鍵操作和內存受限環境的應用程序中。通過正確利用字符串駐留,您可以確保您的程序運行得更高效並更好地利用可用資源。

一文掌握Python 的字符串駐留是如何工作的 - 天天要聞

科技分類資訊推薦

「閃燈即推+邊推邊開」!太原機場開啟高效運行新模式 - 天天要聞

「閃燈即推+邊推邊開」!太原機場開啟高效運行新模式

近日,東航MU5273航班在T2站坪順利完成「閃燈即推+邊推邊開」新流程操作,這標誌着航空器地面高效運行新模式在太原國際機場有限責任公司正式投入應用。資料圖 據介紹,太原機場公司二跑道預計在2025年底正式投運。經模擬機測算,航空器地面滑行距離、滑行時間將顯著增加。不僅直接衝擊航班正常性,也將極大影響機場整體運行...
特斯拉官宣Model 3長續航全輪驅動版28.55萬起售 - 天天要聞

特斯拉官宣Model 3長續航全輪驅動版28.55萬起售

7月1日,特斯拉官方微博宣布Model 3長續航全輪驅動版車型升級,CLTC續航升至753公里,百公里加速升至3.8秒,售價28.55萬元起。特斯拉表示,7月31日(含)前下單,還可享8000元限時保險補貼、5年0息、8000元車漆選裝金等購車優惠政策。...
央視新聞報道:全國加能站充電樁配置率達45% - 天天要聞

央視新聞報道:全國加能站充電樁配置率達45%

報名 | 掃描上圖二維碼,鎖定超級沙龍重慶站席位 產品 | 掃描上方二維碼提交需求 可高效對接 本文來源 | 中國石油石化6月28日,2025能源產業生態論壇在北京召開。論壇上發佈了《中國加油(能)站發展藍皮書2024-2025》,數據顯示,當前,傳統加油站正從單一能源供給,向綜合服務生態深度轉型。《藍皮書》顯示,截至2024年底...
韋東奕,民族的脊樑,崇尚他,國家民族更有前途和希望 - 天天要聞

韋東奕,民族的脊樑,崇尚他,國家民族更有前途和希望

最近,北大韋神韋東奕又「霸屏」了。這位北京大學助理教授、數學科學學院微分方程教研室研究員,因開通個人網絡賬號,兩天漲粉兩千萬。這是什麼概念?一般頭部網絡主播,即便有團隊共同打造賬號,要漲粉兩千萬,沒有幾年時間也難以達成。這說明什麼?
厲害!榮耀400系列三周激活量超70萬台 - 天天要聞

厲害!榮耀400系列三周激活量超70萬台

上周行業消息顯示榮耀400系列全球激活量已經突破100萬台,還引起了行業的熱議。大家都在講這一次榮耀400系列的銷量確實牛,市場認可度確實高。不過當時給出的是全球數據,並不知道國內與海外的佔比。
YU7銷量為何沒受前段時間小米負面的影響? - 天天要聞

YU7銷量為何沒受前段時間小米負面的影響?

為什麼前段時間小米負面不斷,但是現在SU7發佈之後,一樣是賣爆了呢?其實我之前就說過了,這些負面不會影響到小米的銷量。互聯網是健忘的。之前那個小米手機發生高速車禍,很多人在說小米的自駕問題。但是實際上大家要明白,真正會去買小米這個汽車的人,他們的側重點是什麼?
華為發佈新一代OceanStor Dorado 3000融合全閃存存儲:最高1600塊SSD、8PiB容量 - 天天要聞

華為發佈新一代OceanStor Dorado 3000融合全閃存存儲:最高1600塊SSD、8PiB容量

快科技6月30日消息,華為今日正式發佈新一代OceanStor Dorado 3000融合全閃存存儲。最大支持2 TB內存、1600塊SSD,提供高達8 PiB(‌1PiB=1024TB)可用容量,單系統最大可擴展到16個控制器。具有以下三大優勢:全新融合:華為新一代OceanStor Dorado 3000採用原生塊、文件、對象並行架構,一套存儲滿足多種業