我们可以通过这种方式击败小整数实习生(通过计算可以避免缓存层):
>>> n = 674039
>>> one1 = 1
>>> one2 = (n ** 9 + 1) % (n ** 9)
>>> one1 == one2
True
>>> one1 is one2
False
你如何击败小字符串实习生,即看到以下结果:
>>> one1 = "1"
>>> one2 = <???>
>>> type(one2) is str and one1 == one2
True
>>> one1 is one2
False
^{str
实例来避免缓存层
因为实习是基于实施细节的,所以依赖于未记录的实施细节的答案是可以/预期的
Unicode只包含一个字符(值小于128或更精确地从
latin1
)是最复杂的情况,因为这些字符串不是真正的interned,而是(更类似于整数池或与bytes
的行为相同)在开始时创建,只要解释器处于活动状态are stored in an array:因此,每次创建长度为1的unicode时,如果字符值位于} 中:
latin1
-数组中,则会查找该字符值。例如在^{有人甚至会说,如果有一种方法可以在解释器中绕过这一点——我们说的是一个(性能)bug
一种可能性是我们自己使用C-API填充unicode数据。我使用
Cython
来证明概念,但是ctypes
也可以用于相同的效果:值得注意的细节:
PyUnicode_New
将不会在latin1
中查找,因为尚未设置字符李>127
作为maxchar
传递给PyUnicode_New
。因此,我们可以通过PyUnicode_1BYTE_DATA
来解释数据,这样就可以轻松地手动操作数据,而无需太多麻烦李>现在:
如你所愿
下面是一个类似的想法,但通过
ctypes
实现:值得注意的细节:
PyUnicode_1BYTE_DATA
与ctypes一起使用,因为它是一个宏。另一种方法是计算到data
-成员的偏移量,并直接访问该内存(但它取决于平台,感觉不是很可移植)PyUnicode_CopyCharacters
(可能还有其他实现相同的可能性),这比直接计算/访问内存更抽象和可移植李>_PyUnicode_FastCopyCharacters
,因为PyUnicode_CopyCharacters
将检查目标unicode是否有多个引用并抛出_PyUnicode_FastCopyCharacters
不执行这些检查,而是按要求执行李>现在:
对于长度超过1个字符的字符串,更容易避免插入,例如:
相关问题 更多 >
编程相关推荐