一文掌握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 的字符串驻留是如何工作的 - 天天要闻

科技分类资讯推荐

获巨额云计算合同!甲骨文股价创新高 - 天天要闻

获巨额云计算合同!甲骨文股价创新高

智通财经APP获悉,甲骨文(ORCL.US)表示,该公司已签署一项年收入高达300亿美元的单一云计算服务合同,这一金额已超过其当前整个云基础设施业务的规模。受该消息推动,甲骨文股价周一早盘一度上涨8.6%,创下盘中历史新高,收盘涨近4%。今年以来,甲骨文股价已累计上涨约32%。甲骨文在周一提交的一份监管文件中披露,这笔收入...
中金:运营商配合意愿亟待提升 eSIM热度有望重启 - 天天要闻

中金:运营商配合意愿亟待提升 eSIM热度有望重启

智通财经APP获悉,中金发布研报称,根据GSMA Intelligence预测,至2025年底,全球预计将有约10亿eSIM智能手机连接,2030年将增长至69亿,随着消费电子轻薄化、可穿戴设备以及物联网终端漫游需求增加,eSIM的应用有望在2025年加速。但eSIM的应用落地仍面临运营商配合意愿度不高的阻力,支持终端数量有限。eSIM卡具备小尺寸、...
网易腾讯发布暑期限玩日历:未成年人每周限玩3小时 - 天天要闻

网易腾讯发布暑期限玩日历:未成年人每周限玩3小时

随着暑期来临,未成年人网络使用需求显著上升。为防止未成年人沉迷游戏,6月30日,网易游戏、腾讯游戏分别发布了2025年暑期未成年人限玩日历(7月1日-8月31日),两家企业均采取严格时段限制措施,规则基本一致。
“闪灯即推+边推边开”!太原机场开启高效运行新模式 - 天天要闻

“闪灯即推+边推边开”!太原机场开启高效运行新模式

近日,东航MU5273航班在T2站坪顺利完成“闪灯即推+边推边开”新流程操作,这标志着航空器地面高效运行新模式在太原国际机场有限责任公司正式投入应用。资料图 据介绍,太原机场公司二跑道预计在2025年底正式投运。经模拟机测算,航空器地面滑行距离、滑行时间将显著增加。不仅直接冲击航班正常性,也将极大影响机场整体运行...