Python 3.x sys.intern()的作用是什么?应该在什么时候使用它?
我遇到了字典的内存管理,其中提到了intern功能。它到底做什么,什么时候使用Python 3.x sys.intern()的作用是什么?应该在什么时候使用它?,python-3.x,dictionary,memory,memory-management,sys,Python 3.x,Dictionary,Memory,Memory Management,Sys,我遇到了字典的内存管理,其中提到了intern功能。它到底做什么,什么时候使用 举个例子:如果我有一个名为的集合seen,它包含形式为(string1,string2)的元组,我用它来检查重复的元组,那么存储(intern(string1),intern(string2))会提高性能吗 因此,如果您有许多相等的字符串实例,则可以节省内存,此外,您还可以通过标识(而不是更快的相等值)比较规范化字符串。来自文档: 在“interned”字符串表中输入字符串并返回 插入字符串–字符串本身或副本。实习字
举个例子:如果我有一个名为的集合seen,它包含形式为(string1,string2)的元组,我用它来检查重复的元组,那么存储(intern(string1),intern(string2))会提高性能吗 因此,如果您有许多相等的字符串实例,则可以节省内存,此外,您还可以通过标识(而不是更快的相等值)比较规范化字符串。来自文档: 在“interned”字符串表中输入字符串并返回 插入字符串–字符串本身或副本。实习字符串 如果 字典中的键是插入的,查找键是插入的 键比较(在散列之后)可以通过指针比较来完成 而不是字符串比较。通常,Python中使用的名称 程序被自动插入,字典被用来保存 模块、类或实例属性具有内部密钥 插入的字符串不是不朽的;您必须保留对 返回intern()的值以从中获益 澄清: 如文档所示,
sys.intern
功能旨在用于性能优化
sys.intern
函数维护一个包含interned字符串的表。当您尝试插入字符串时,函数会在表中查找该字符串,并执行以下操作:
>>> import sys
>>> a = sys.intern('why do pangolins dream of quiche')
>>> a
'why do pangolins dream of quiche'
>>> b = sys.intern('why do pangolins dream of quiche')
>>> b
'why do pangolins dream of quiche'
在上面的示例中,a
保存插入的字符串。尽管不可见,sys.intern
函数已在interned strings表中保存了“穿山甲为何梦见乳蛋饼”
字符串对象>>> import sys
>>> a = sys.intern('why do pangolins dream of quiche')
>>> a
'why do pangolins dream of quiche'
>>> b = sys.intern('why do pangolins dream of quiche')
>>> b
'why do pangolins dream of quiche'
>>> import sys
>>> a = sys.intern('why do pangolins dream of quiche')
>>> a
'why do pangolins dream of quiche'
>>> b = sys.intern('why do pangolins dream of quiche')
>>> b
'why do pangolins dream of quiche'
即使它不是立即可见的,因为字符串“穿山甲为什么会梦见乳蛋饼”
以前已经被实习过,b
现在保存着与a
相同的字符串对象
>>> b is a
True
如果我们不使用intern创建相同的字符串,那么最终会得到两个具有相同值的不同字符串对象
>>> c = 'why do pangolins dream of quiche'
>>> c is a
False
>>> c is b
False
通过使用
sys.intern
确保在请求创建与现有字符串对象具有相同值的第二个字符串对象时,不会创建具有相同值的两个字符串对象,从而收到对先前存在的字符串对象的引用。这样,您就节省了内存。此外,字符串对象比较现在非常有效,因为它是通过比较两个字符串对象的内存地址而不是内容来执行的。他们没有谈论关键字intern
,因为Python中没有这样的东西。他们在谈论。在py3k中已移动到。文档有详尽的描述。本质上,intern在一组内部字符串中查找(或存储,如果不存在)字符串,因此所有内部实例将共享相同的标识。您可以用查找此字符串的一次性成本来换取更快的比较(在检查标识后,比较可以返回True,而不必比较每个字符),并减少内存使用
然而,python会的,因此您可能会发现您没有得到任何改进,因为您的字符串已经在幕后被拘留了。例如:
>>> a = 'abc'; b = 'abc'
>>> a is b
True
在过去,一个缺点是被拘留的字符串是永久性的。一旦插入,即使删除了所有引用,字符串内存也永远不会被释放。我认为python的最新版本不再如此。CPython将自动插入较小的字符串-这是一种实现行为,不能保证所有实现都是如此(但很可能是如此)。CPython将自动插入较小的字符串,但前提是它们在代码中是常量表达式,而不是在运行时创建的字符串。请参阅stackoverflow.com/questions/15541404/python-string-interning。如果我们将代码写在
.py
文件中并执行此操作,我们会得到c是一个asTrue
。为什么会这样?@ShashankSingh我的理解是,当python文件被编译成PYC文件时,它会在文件中创建一个常量列表,在本例中是字符串,它显示的任何地方都引用常量,而不是重新创建字符串。因此,当文件被读取时,所有分配字符串“why do…”的事件都分配给该字符串的同一个实例。我想把这篇文章放在这里,它还提供了关于这个非常好的问题的有趣示例和概念: