为什么提早归还比其他要慢?

为什么提早归还比其他要慢?,第1张

为什么提早归还比其他要慢?

这纯粹是猜测,我还没有找到一种简单的方法来检查它是否正确,但是我有一个理论适合您。

尝试了您的代码并获得了相同的结果,但

without_else()
反复地比
with_else()

>>> T(lambda : without_else()).repeat()[0.42015745017874906, 0.3188967452567226, 0.31984281521812363]>>> T(lambda : with_else()).repeat()[0.36009842032996175, 0.28962249392031936, 0.2927151355828528]>>> T(lambda : without_else(True)).repeat()[0.31709728471076915, 0.3172671387005721, 0.3285821242644147]>>> T(lambda : with_else(True)).repeat()[0.30939889008243426, 0.3035132258429485, 0.3046679117038593]

考虑到字节码是相同的,唯一的区别是函数的名称。尤其是时序测试会在全局名称上进行查找。尝试重命名

without_else()
,区别消失:

>>> def no_else(param=False):    if param:        return 1    return 0>>> T(lambda : no_else()).repeat()[0.3359846013948413, 0.29025818923918223, 0.2921801513879245]>>> T(lambda : no_else(True)).repeat()[0.3810395594970828, 0.2969634408842694, 0.2960104566362247]

我的猜测是,

without_else
它与其他内容发生了哈希冲突,
globals()
因此全局名称查找稍微慢一些。

编辑 :具有7个或8个键的字典可能具有32个插槽,因此在此基础上,

without_else
哈希值与
__builtins__

>>> [(k, hash(k) % 32) for k in globals().keys() ][('__builtins__', 8), ('with_else', 9), ('__package__', 15), ('without_else', 8), ('T', 21), ('__name__', 25), ('no_else', 28), ('__doc__', 29)]

要阐明哈希如何工作:

__builtins__
散列为-1196389688,这减小了表大小(32)的模数,这意味着它存储在表的#8插槽中。

without_else
哈希到505688136,将模32的值降低为8,因此发生冲突。要解决此问题,Python计算:

从…开始:

j = hash % 32perturb = hash

重复此过程,直到找到可用的插槽:

j = (5*j) + 1 + perturb;perturb >>= 5;use j % 2**i as the next table index;

这使它可以用作下一个索引17。幸运的是,它是免费的,因此循环仅重复一次。哈希表的大小是2的幂,哈希表的大小也是2的幂

2**i
i
是哈希值使用的位数
j

对该表的每个探测都可以找到以下之一:

  • 插槽为空,在这种情况下,探测停止,并且我们知道该值不在表中。

  • 该广告位尚未使用,但已在过去使用过,在这种情况下,我们尝试使用如上计算的下一个值。

  • 插槽已满,但存储在表中的完整哈希值与我们要查找的键的哈希值不同(在

    __builtins__
    vs的情况下就是这样
    without_else
    )。

  • 插槽已满,并且正好具有我们想要的哈希值,然后Python检查以查看键和我们正在查找的对象是否是同一对象(在这种情况下,这是因为可能是标识符的短字符串已被插入,所以相同的标识符使用完全相同的字符串)。

  • 最终,当插槽已满时,哈希完全匹配,但是键不是同一对象,然后Python才会尝试比较它们是否相等。这相对较慢,但实际上不应该进行名称查找。



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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存