当字符串中有一个点时,为什么“ is”关键字具有不同的行为?

当字符串中有一个点时,为什么“ is”关键字具有不同的行为?,第1张

当字符串中有一个点时,为什么“ is”关键字具有不同的行为?

is
验证对象的身份,和Python,任何执行时,它符合字面不变类型的,是完全自由 要么 做出不可变类型的新对象,
通过该类型的现有对象觅见,如果他们中的一些可重复使用(通过添加对相同基础对象的新引用)。这是优化的一个务实的选择并 没有
受到语义约束,所以你的代码不应该依赖于该路径的给予实施可能要(或者它可能与Python的bug修正/优化版本破门!)。

考虑例如:

>>> import dis>>> def f():...   x = 'google.com'...   return x is 'google.com'... >>> dis.dis(f)  20 LOAD_ConST    1 ('google.com')   3 STORE_FAST    0 (x)  36 LOAD_FAST     0 (x)   9 LOAD_ConST    1 ('google.com')  12 COMPARE_OP    8 (is)  15 RETURN_VALUE

因此,在此特定实现中, 在function内 ,您的观察结果不适用,并且为文字(任何文字)仅创建了一个对象,并且实际上:

>>> f()True

实用上讲,这是因为在函数中通过常量的本地表(通过不制作多个足以满足要求的常量不可变对象来节省内存)非常便宜和快速,并且由于可以重复调用该函数,因此可以提供良好的性能返回之后。

但是, 在交互式提示符下 ,实现了相同的实现( 编辑 :我本来以为这也会在模块的顶层发生,但是@Thomas的评论使我正确了,请参阅下文):

>>> x = 'google.com'>>> y = 'google.com'>>> id(x), id(y)(4213000, 4290864)

不必费心尝试以这种方式节省内存

id
-s是不同的,即不同的对象。可能会有更高的成本和更低的回报,因此此实现的优化程序的启发式方法告诉它不要费心搜索,而只是继续进行。

编辑 :根据@Thomas的观察,在模块顶层,例如:

$ cat aaa.pyx = 'google.com'y = 'google.com'print id(x), id(y)

再次,我们在此实现中看到基于常量表的内存优化:

>>> import aaa4291104 4291104

(根据@Thomas的观察,编辑结束)。

最后,再次在相同的实现上:

>>> x = 'google'>>> y = 'google'>>> id(x), id(y)(2484672, 2484672)

启发式方法在这里是不同的,因为文字字符串“看起来像是一个标识符”-因此它可能在需要进行intern *** 作的 *** 作中使用…因此,优化程序仍然会对其进行intern(并且一旦intern,查找它就会变得非常快课程)。确实,令人惊讶……

>>> z = intern(x)>>> id(z)2484672

x
已经
intern
编在第一次(正如你看到的,返回值
intern
相同的
对象
x
y
,因为它具有相同
id()
)。当然,你不应该依赖此任-优化并不 具备 自动实习生什么,它只是一个优化启发式;
如果您需要
intern
ed字符串,则必须
intern
明确指定它们,以确保安全。当您显式地 执行内部 字符串时…:

>>> x = intern('google.com')>>> y = intern('google.com')>>> id(x), id(y)(4213000, 4213000)

…然后您 可以 确保

id()
每次都获得完全相同的对象(即相同的)结果-
因此您可以应用微优化,例如使用进行检查,
is
而不是
==
(我几乎从未发现微不足道的性能提升值得麻烦;-)。

编辑 :只是为了澄清一下,这是我正在谈论的性能差异,在慢速的Macbook Air上…:

$ python -mtimeit -s"a='google';b='google'" 'a==b'10000000 loops, best of 3: 0.132 usec per loop$ python -mtimeit -s"a='google';b='google'" 'a is b'10000000 loops, best of 3: 0.107 usec per loop$ python -mtimeit -s"a='goo.gle';b='goo.gle'" 'a==b'10000000 loops, best of 3: 0.132 usec per loop$ python -mtimeit -s"a='google';b='google'" 'a is b'10000000 loops, best of 3: 0.106 usec per loop$ python -mtimeit -s"a=intern('goo.gle');b=intern('goo.gle')" 'a is b'10000000 loops, best of 3: 0.0966 usec per loop$ python -mtimeit -s"a=intern('goo.gle');b=intern('goo.gle')" 'a == b'10000000 loops, best of 3: 0.126 usec per loop

……最多两种方式都只有几十纳秒。因此,即使仅在最极端的情况下也要 考虑 “从此[删除的性能]性能瓶颈中优化[删除的性能]”!-)



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5630271.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存