sys.intern() 的核心用途是加速高频重复字符串的身份比较(is),而非节省内存;它仅对编译期确定的合法标识符字面量自动驻留,手动调用才可控,但驻留后永不释放且有哈希查找开销。

sys.intern() 不是为了“优化短字符串的存储空间”而设计的,它真正起效的场景是高频重复字符串的身份比较。短字符串看起来“被优化了”,其实是自动驻留的副作用,不是目标。
自动驻留只发生在编译期确定的合格字面量上
Python 解释器在编译源码时,会对满足以下全部条件的字符串字面量做隐式驻留:- 内容仅含 ASCII 字母、数字、下划线(即符合 Python
identifier规则) - 长度 ≤ 20(CPython 3.10+ 默认阈值,部分版本可能略宽松)
- 直接写死在代码里,不是拼接、格式化或运行时构造(如
"a" + "b"、f"{x}"、input())
a = "user_id" 和 b = "user_id" 在同一模块中通常 a is b 为 True;但 c = "user id"(含空格)或 d = "x" * 21 就不会。
手动调用 sys.intern() 才是可控手段
当你需要确保两个相同内容的字符串指向同一对象(比如 CSV 表头、HTTP header 名、数据库字段名),必须显式调用:
import sys
field1 = sys.intern(line.split(",")[0])
field2 = sys.intern("status")
注意:
- 驻留后的字符串永不释放——内存只增不减,直到解释器退出
- 每次调用
sys.intern()都要查哈希表,有开销;不要对每行strip()都调用 - 多线程安全,但高并发频繁调用可能成为瓶颈
is 比 == 快,但仅当对象真正驻留时才成立
字符串比较性能差异只在驻留后体现:
-
a is b是指针比较,O(1) -
a == b是逐字符比对,O(n),且需先检查长度
a 和 b 确实被驻留了。否则 is 返回 False,逻辑错误比慢更危险。
真正容易被忽略的是:驻留不是为了省几字节内存,而是为了解决大量重复字符串带来的身份判等开销。如果你没在做高频 is 比较,或者字符串来源不可控(如用户输入、文件读取),强行驻留只会增加内存负担,没有实际收益。


















