百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

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

off999 2024-09-14 07:08 47 浏览 0 评论

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 代码,尤其是在处理大量字符串、性能关键操作和内存受限环境的应用程序中。通过正确利用字符串驻留,您可以确保您的程序运行得更高效并更好地利用可用资源。

相关推荐

office2007密钥 office2016(office2007ultimate密钥)

word2016激活密钥有两种类型:永久激活码和KMS期限激活密钥。其中,永久激活密钥可以使用批量授权版永久激活密钥进行激活,如所示;而KMS期限激活密钥需要使用KMS客户端密钥进行激活,如所示。另外...

windows10系统启动盘制作(windows10启动盘制作教程)

Windows10系统更改启动磁盘的方法如下1、按快捷键Win+R,调出命令窗口2、输入msconfig,点【确定】3、在系统配置中,选择【引导】菜单4、选择要默认启动的磁盘,点【设置为默认值】,...

方正电脑怎么重装系统

购买一张系统盘,然后启动电脑,将购买的系统盘插入电脑光驱中,等待光驱读取系统盘后,点击安装系统,即可自动安装,等待安装完毕,电脑会自动重启,重新启动后,电脑的系统就安装完毕,可以使用了一、准备需要的软...

qq邮箱怎么写才正确
qq邮箱怎么写才正确

步骤/方式1一般默认的QQ邮箱格式是:QQ号码@qq.com,即QQ账号+@qq.com后缀步骤/方式2若要发送邮件,也要在对方的qq帐号末尾加上@qq.com1.每个人在注册QQ时都会有关联的一个邮箱,它的格式就是“QQ号码@qq.com...

2025-12-21 18:51 off999

电脑怎么看配置信息
电脑怎么看配置信息

要查看Windows电脑的配置信息,可以通过按下Win键+R,然后在弹出的运行对话框中输入“dxdiag”并按回车键打开DirectX诊断工具,可以查看有关处理器、内存、显卡等硬件信息。另外,还可以右键点击“此电脑”,选择“属性”来查看...

2025-12-21 18:03 off999

mpeg是什么格式(mpeg是什么格式和mp4的区别)

是视频格式,是电脑视频文件的一种,相对其它视频文件格式而言,mpeg格式占的存储空间相对比较小,那么像素也就相对比较低,图像也没有其它格式那么高清,不过一般情况下已经满足正常的使用。好多视频文件都是采...

电脑参数配置怎么选(电脑参数配置怎么选择)

1、CPU,这个主要取决于频率和二级缓存,三级缓存,核心数量。频率越高、二级缓存越大,三级缓存越大,核心越多,运行速度越快。速度越快的CPU只有三级缓存影响响应速度。2、内存,内存的存取速度取决于接口...

windows7字体(Windows7字体库在哪)

win7系统默认中文字体是微软雅黑字体1、首先我们先打开个性化2、然后我们打开“窗口颜色”3、然后我们点击“项目”里的桌面,选择“已选定的项目”4、下面就可以改字体,还有字体的颜色、大小5、然后点击“...

windows7x86是32位吗(windows7 x86)

X86不是代表操作系统,是代表的CPU的类型,如果你知道CPU的发展史就知道,个人用计算机的CPU很早的版本是从286、386、486、586、奔腾等等类型发展起来的,所以X86的代表PC的CPU的类...

固态硬盘删除后又自动恢复了

进入BIOS查看,第一启动项是不是UEFI引导,改掉它可以下载个pe,下载安装在本地磁盘里,重启进入pe工具,先给固态格式化分区,在ghost机械盘上的系统,还原到固态上。遇到这种情况一定不要在此...

win10版本回退(win10回退到以前版本)

如果你想在Windows10系统中回退到上一个版本,可以按照以下步骤进行操作:1.打开设置:点击Windows开始按钮,然后点击屏幕左侧的“设置”图标,或者使用键盘快捷键Win+I打开设置。2...

营业厅一个路由器多少钱(上门更换路由器收费吗)

移动免费装宽带活动全国都在搞,不过免费是有“门槛”的。以我所在的地区为例,只有月费在78元及以上的大流量套餐用户,才可以享受免费安装移动的宽带。月费越高,宽带的速率也越高,148元档可以安装200M的...

win10从u盘启动怎么设置(win10怎么从u盘启动电脑)

1.回到桌面。点击开始徽标,点击开始菜单左侧的设置。2.设置界面点击更新和安全。3.进入更新和安全界面,点击左侧的恢复选项。4.进入恢复界面,点击高级启动下面的立即重新启动。5.插入自己的U盘,等待...

系统大全网站(系统大全网站推荐)

下载时发生错误可能是以下原因:1.你的网速过慢,网页代码没有完全下载就运行了,导致不完整,当然就错误了。请刷新。2.网页设计错误,导致部分代码不能执行。请下载最新的遨游浏览器。3.你的浏览器不兼容导致...

win10官方启动盘(win10官方启动盘怎么用)

1、在开始菜单搜索“设置”,打开“设置”;2、点击“更新与安全”,在左侧菜单栏点击“恢复”;3、点击“启动项”,在弹出的窗口中会显示当前可以启动的项目,点击“编辑”;4、在打开的“编辑启动项”窗口中,...

取消回复欢迎 发表评论: