考虑:
a = str(123456789)
b = str(123456789)
a is b # False
后一行评估为False
因为a
和b
不是同一个对象,即使它们可能是(因为字符串是不可变的)。因此,如果我有很多"副本"在相同的字符串存活,我可能正在使用比我需要更多的内存。这就是intern
(Py2)和sys.intern
(Py3)存在的原因!
a = intern(str(123456789))
b = intern(str(123456789)) # Call to "intern" technically pointless
a is b # True
从内存角度来看使用intern
是否有任何不足之处? (因此超出调用函数的微小时间成本。)我从文档(例如https://docs.python.org/2/library/functions.html#intern)中了解到,只要我保持对它的引用,字符串只保留在实习表中,所以在只有一个字符串副本的情况,应该使用相同数量的内存直接分配给字符串,如果我有多个副本,那么当我实习时显然内存使用率会降低。
答案 0 :(得分:3)
可能有两个缺点:
使用sys.intern()
电话的CPU成本。调用函数需要将当前帧推入堆栈并在函数返回时再次弹出。如果你为 lot 字符串执行此操作,则会增加成本。这是CPU周期与内存需要考虑的权衡。
如果您的字符串主要是单独使用,则最终可能会使用 more 内存。 Interning还在哈希表中查找字符串对象,这必然需要分配比存储的字符串数量更多的内存槽。使用具有N +开销百分比插槽的散列表可能超过N个字符串所需的内存,每个字符串不经常使用,因此不会重复。
也就是说,我们已经成功地使用了实习,并且在数GB的内存缓存中发挥了重要作用,其中字符串必然出现在树结构中的多个位置。
答案 1 :(得分:2)
课程的记忆减少取决于"重复" 的数量。如果没有重复,这实际上只消耗更多内存,因为Python 存储哈希表来为内部进程执行查找(它以某种方式具有检查字符串是否已存在。)
此外还有字符串实习的两个优点:(1)更快的相等性检查:您只需比较引用(与此处is
一样) ; (2)通常减少记忆,因为你当然的目标是实习生和有趣的"字符串。