缺少实习字符串?

时间:2017-01-26 14:42:10

标签: python

考虑:

a = str(123456789)
b = str(123456789)
a is b # False

后一行评估为False因为ab不是同一个对象,即使它们可能是(因为字符串是不可变的)。因此,如果我有很多"副本"在相同的字符串存活,我可能正在使用比我需要更多的内存。这就是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)中了解到,只要我保持对它的引用,字符串只保留在实习表中,所以在只有一个字符串副本的情况,应该使用相同数量的内存直接分配给字符串,如果我有多个副本,那么当我实习时显然内存使用率会降低。

2 个答案:

答案 0 :(得分:3)

可能有两个缺点:

  • 使用sys.intern()电话的CPU成本。调用函数需要将当前帧推入堆栈并在函数返回时再次弹出。如果你为 lot 字符串执行此操作,则会增加成本。这是CPU周期与内存需要考虑的权衡。

  • 如果您的字符串主要是单独使用,则最终可能会使用 more 内存。 Interning还在哈希表中查找字符串对象,这必然需要分配比存储的字符串数量更多的内存槽。使用具有N +开销百分比插槽的散列表可能超过N个字符串所需的内存,每个字符串不经常使用,因此不会重复。

也就是说,我们已经成功地使用了实习,并且在数GB的内存缓存中发挥了重要作用,其中字符串必然出现在树结构中的多个位置。

答案 1 :(得分:2)

课程的记忆减少取决于"重复" 的数量。如果没有重复,这实际上只消耗更多内存,因为Python 存储哈希表来为内部进程执行查找(它以某种方式具有检查字符串是否已存在。)

此外还有字符串实习的两个优点:(1)更快的相等性检查:您只需比较引用(与此处is一样) ; (2)通常减少记忆,因为你当然的目标是实习生和有趣的"字符串。