一文掌握Python 的字符串驻留是如何工作的
off999 2024-09-14 07:08 20 浏览 0 评论
Python 是一种灵活的编程语言,它提供了各种机制来优化性能和内存使用情况。其中一种优化技术就是字符串驻留。
字符串驻留
字符串驻留是一个根植于内存和性能优化的概念,尤其是在 Python 等编程语言中。
什么是字符串驻留?
字符串驻留的核心是只存储每个不同不可变字符串值的一个副本。不可变字符串一旦创建就无法更改。这种不变性是驻留过程的关键,因为它确保存储的字符串值保持不变,从而允许多个引用安全地指向同一内存位置。
当一个字符串被驻留时,任何其他具有相同值的字符串都将引用相同的内存位置。这意味着 Python 不会为相同的字符串创建新的内存分配,而是重用现有的内存分配。这种重用使字符串驻留成为一种有效的优化技术。
为什么字符串驻留很有用?
字符串驻留有几个显著的好处:
- 内存效率:通过仅存储相同字符串的一个副本,Python 减少了使用的内存量。这对于处理大量重复字符串值的应用程序(例如文本处理、数据解析和日志系统)尤其有益。
- 性能改进:驻留字符串可以加快比较速度。通常,比较两个字符串需要逐个检查每个字符,这对于长字符串来说可能非常耗时。但是,如果字符串被驻留,Python 可以简单地比较它们的内存地址。如果地址相同,则字符串相等。这种指针比较比逐个字符比较快得多。
- 一致性和安全性:字符串驻留有助于保持一致性,并避免因拥有同一字符串的多个副本而可能出现的潜在错误。由于驻留字符串是不可变的且存储在单个位置,因此无意中修改一个字符串(如果字符串是可变的)不会影响其他字符串,从而确保数据完整性。
何时应使用字符串驻留?
了解字符串驻留有益的场景可以帮助您做出明智的决定,确定何时在代码中使用它:
- 重复字符串的高频率:如果您的应用程序涉及处理大量重复字符串,则驻留可以显著节省内存并提高性能。
- 性能关键的字符串比较:在字符串比较是性能瓶颈的情况下,实习可以通过利用指针相等性检查而不是逐个字符的比较来加快比较速度。
- 资源受限的环境:在内存受限的环境中,例如嵌入式系统或在有限硬件上运行的应用程序,驻留可以帮助优化内存使用情况。
限制和注意事项
虽然字符串驻留提供了明显的好处,但重要的是要注意它的局限性:
- 内存开销:驻留需要在内存节省和管理驻留字符串池的开销之间进行权衡。驻留过多的字符串(尤其是较大的字符串)可能会导致驻留字符串池本身的内存使用量增加。
- 垃圾回收:只要引用了 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 自动驻留。因此,a和b引用相同的内存位置,与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'会自动驻留,因此a和b引用相同的内存位置。但是,较长的字符串'longer_string_that_is_not_interned'不会自动驻留,因此m和n引用不同的内存位置。
手动驻留
对于未自动驻留的字符串,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'不会自动驻留,因此a和b最初引用不同的内存位置。使用之后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
在这些示例中,字符串name和name_1被保留,因为它们看起来像标识符,并且由字母数字字符和下划线组成。因此,a和b引用相同的内存位置,就像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不会自动驻留,因此a和b最初引用不同的内存位置。使用之后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 gui编程框架推荐以及介绍(python gui开发)
-
Python的GUI编程框架有很多,这里为您推荐几个常用且功能强大的框架:Tkinter:Tkinter是Python的标准GUI库,它是Python内置的模块,无需额外安装。它使用简单,功能较为基础...
- python自动化框架学习-pyautogui(python接口自动化框架)
-
一、适用平台:PC(windows和mac均可用)二、下载安装:推荐使用命令行下载(因为会自动安装依赖库):pipinstallPyAutoGUI1该框架的依赖库还是蛮多的,第一次用的同学耐心等...
- Python 失宠!Hugging Face 用 Rust 新写了一个 ML框架,现已低调开源
-
大数据文摘受权转载自AI前线整理|褚杏娟近期,HuggingFace低调开源了一个重磅ML框架:Candle。Candle一改机器学习惯用Python的做法,而是Rust编写,重...
- Flask轻量级框架 web开发原来可以这么可爱呀~(建议收藏)
-
Flask轻量级框架web开发原来可以这么可爱呀大家好呀~今天让我们一起来学习一个超级可爱又实用的PythonWeb框架——Flask!作为一个轻量级的Web框架,Flask就像是一个小巧精致的工...
- Python3使用diagrams生成架构图(python架构设计)
-
目录技术背景diagrams的安装基础逻辑关系图组件簇的定义总结概要参考链接技术背景对于一个架构师或者任何一个软件工程师而言,绘制架构图都是一个比较值得学习的技能。这就像我们学习的时候整理的一些Xmi...
- 几个高性能Python网络框架,高效实现网络应用
-
Python作为一种广泛使用的编程语言,其简洁易读的语法和强大的生态系统,使得它在Web开发领域占据重要位置。高性能的网络框架是构建高效网络应用的关键因素之一。本文将介绍几个高性能的Python网络框...
- Web开发人员的十佳Python框架(python最好的web框架)
-
Python是一种面向对象、解释型计算机程序设计语言。除了语言本身的设计目的之外,Python的标准库也是值得大家称赞的,同时Python还自带服务器。其它方面,Python拥有足够多的免费数据函数库...
- Diagram as Code:用python代码生成架构图
-
工作中常需要画系统架构图,通常的方法是通过visio、processon、draw.io之类的软件,但是今天介绍的这个软件Diagrams,可以通过写Python代码完成架构图绘制,确实很co...
- 分享一个2022年火遍全网的Python框架
-
作者:俊欣来源:关于数据分析与可视化最近Python圈子当中出来一个非常火爆的框架PyScript,该框架可以在浏览器中运行Python程序,只需要在HTML程序中添加一些Python代码即可实现。该...
- 10个用于Web开发的最好 Python 框架
-
Python是一门动态、面向对象语言。其最初就是作为一门面向对象语言设计的,并且在后期又加入了一些更高级的特性。除了语言本身的设计目的之外,Python标准库也是值得大家称赞的,Python甚至还...
- 使用 Python 将 Google 表格变成您自己的数据库
-
图片来自Shutterstock,获得FrankAndrade的许可您知道Google表格可以用作轻量级数据库吗?GoogleSheets是一个基于云的电子表格应用程序,可以像大多数数据库管...
- 牛掰!用Python处理Excel的14个常用操作总结!
-
自从学了Python后就逼迫用Python来处理Excel,所有操作用Python实现。目的是巩固Python,与增强数据处理能力。这也是我写这篇文章的初衷。废话不说了,直接进入正题。数据是网上找到的...
- 将python打包成exe的方式(将python文件打包成exe可运行文件)
-
客户端应用程序往往需要运行Python脚本,这对于那些不熟悉Python语言的用户来说可能会带来一定的困扰。幸运的是,Python拥有一些第三方模块,可以将这些脚本转换成可执行的.exe...
- 对比Excel学Python第1练:既有Excel,何用Python?
-
背景之前发的文章开头都是“Python数据分析……”,使得很多伙伴以为我是专门分享Python的,但我的本意并非如此,我的重点还是会放到“数据分析”上,毕竟,Python只是一种工具而已。现在网上可以...
- 高效办公:Python处理excel文件,摆脱无效办公
-
一、Python处理excel文件1.两个头文件importxlrdimportxlwt其中xlrd模块实现对excel文件内容读取,xlwt模块实现对excel文件的写入。2.读取exce...
你 发表评论:
欢迎- 一周热门
-
-
python 3.8调用dll - Could not find module 错误的解决方法
-
加密Python源码方案 PyArmor(python项目源码加密)
-
Python3.8如何安装Numpy(python3.6安装numpy)
-
大学生机械制图搜题软件?7个受欢迎的搜题分享了
-
编写一个自动生成双色球号码的 Python 小脚本
-
免费男女身高在线计算器,身高计算公式
-
将python文件打包成exe程序,复制到每台电脑都可以运行
-
Python学习入门教程,字符串函数扩充详解
-
Python数据分析实战-使用replace方法模糊匹配替换某列的值
-
Python进度条显示方案(python2 进度条)
-
- 最近发表
-
- python gui编程框架推荐以及介绍(python gui开发)
- python自动化框架学习-pyautogui(python接口自动化框架)
- Python 失宠!Hugging Face 用 Rust 新写了一个 ML框架,现已低调开源
- Flask轻量级框架 web开发原来可以这么可爱呀~(建议收藏)
- Python3使用diagrams生成架构图(python架构设计)
- 几个高性能Python网络框架,高效实现网络应用
- Web开发人员的十佳Python框架(python最好的web框架)
- Diagram as Code:用python代码生成架构图
- 分享一个2022年火遍全网的Python框架
- 10个用于Web开发的最好 Python 框架
- 标签列表
-
- python计时 (54)
- python安装路径 (54)
- python类型转换 (75)
- python进度条 (54)
- python的for循环 (56)
- python串口编程 (60)
- python写入txt (51)
- python读取文件夹下所有文件 (59)
- java调用python脚本 (56)
- python操作mysql数据库 (66)
- python字典增加键值对 (53)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python qt (52)
- python人脸识别 (54)
- python斐波那契数列 (51)
- python多态 (60)
- python命令行参数 (53)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- centos7安装python (53)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)