python sys.intern是做什么的,什么时候应该使用它?

2024-05-12 20:52:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我遇到了关于字典内存管理的this question,其中提到了intern函数。它具体做什么,什么时候使用?

举个例子:

如果我有一个名为seen的集合,它包含形式为(string1,string2)的元组,我用它来检查重复项,那么存储(intern(string1),intern(string2))会提高w.r.t.内存或速度的性能吗?


Tags: 函数内存字典this性能速度形式例子
3条回答

他们没有谈论关键字intern,因为在Python中没有这样的东西。他们在谈论non-essential built-in function ^{}。它在py3k中被移到^{}。文档有详尽的描述。

实际上,intern会在一组已实习的字符串中查找(或存储(如果不存在)该字符串,因此所有已实习的实例将共享相同的标识。您可以用查找此字符串的一次性成本换取更快的比较(只需检查标识,而不必比较每个字符,比较就可以返回True),并减少内存使用。

然而,python将automatically intern strings that are small, or look like identifiers,因此您可能会发现您没有任何改进,因为您的字符串已经在幕后被截获。例如:

>>> a = 'abc'; b = 'abc'
>>> a is b
True

在过去,一个缺点是,实习的字符串是永久的。一旦被实习,字符串内存就永远不会被释放,即使在所有引用都被删除之后。不过,我认为这不再适用于较新版本的python。

来自Python 3文档

sys.intern(string)

Enter string in the table of “interned” strings and return the interned string – which is string itself or a copy. Interning strings is useful to gain a little performance on dictionary lookup – if the keys in a dictionary are interned, and the lookup key is interned, the key comparisons (after hashing) can be done by a pointer compare instead of a string compare. Normally, the names used in Python programs are automatically interned, and the dictionaries used to hold module, class or instance attributes have interned keys.

Interned strings are not immortal; you must keep a reference to the return value of intern() around to benefit from it.

澄清:

如文档所示,sys.intern函数旨在用于性能优化。

sys.intern函数维护一个包含内部字符串的表。当尝试实习字符串时,函数会在表中查找该字符串并:

  1. 如果字符串不存在(尚未实习),函数将保存 它在表中,并从interned strings表返回。

    >>> import sys
    >>> a = sys.intern('why do pangolins dream of quiche')
    >>> a
    'why do pangolins dream of quiche'
    

    在上面的示例中,a保存实习字符串。尽管不可见,sys.intern函数已将'why do pangolins dream of quiche'字符串对象保存在interned strings表中。

  2. 如果字符串存在(已被截取),函数将从 实习字符串表。

    >>> b = sys.intern('why do pangolins dream of quiche')
    >>> b
    'why do pangolins dream of quiche'
    

    尽管它不是立即可见的,因为字符串'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可以确保在请求创建与现有字符串对象具有相同值的第二个字符串对象时,不会创建具有相同值的两个字符串对象,从而接收到对先前存在的字符串对象的引用。这样,您就节省了内存。另外,字符串对象比较现在非常有效,因为它是通过比较两个字符串对象的内存地址而不是它们的内容来执行的。

相关问题 更多 >