【问题标题】:Why is hash() slower under python3.4 vs python2.7为什么在 python3.4 vs python2.7 下 hash() 慢
【发布时间】:2016-10-19 16:37:45
【问题描述】:

我正在使用 timeit 进行一些性能评估,发现 python 2.7.10 和 python 3.4.3 之间的性能下降。我把它缩小到hash()函数:

python 2.7.10:

>>> import timeit
>>> timeit.timeit('for x in xrange(100): hash(x)', number=100000)
0.4529099464416504
>>> timeit.timeit('hash(1000)')
0.044638872146606445

python 3.4.3:

>>> import timeit
>>> timeit.timeit('for x in range(100): hash(x)', number=100000)
0.6459149940637872
>>> timeit.timeit('hash(1000)')
0.07708719989750534

这是一个大约。 40%退化!整数、浮点数、字符串(unicodes 或 bytearrays)等是否被散列似乎并不重要;退化是差不多的。在这两种情况下,哈希都返回一个 64 位整数。以上是在我的 Mac 上运行的,在 Ubuntu 机器上的降级较小(20%)。

我还在 python2.7 测试中使用了 PYTHONHASHSEED=random,在 一些 案例中,为每个“案例”重新启动 python,我看到 hash() 的性能变得更糟了,但是从来没有python3.4那么慢

有人知道这里发生了什么吗?是否为 python3 选择了更安全但更慢的哈希函数?

【问题讨论】:

  • 哈希函数绝对不安全。它不打算用作加密哈希。它的主要用途是用于dicts 和sets。
  • 斯文:我明白。请阅读第一段:我没有将它用于加密目的。事实上,我根本没有直接使用 hash(),但我相信这是为什么 python3.4 下的 somedict[someindex] 比 python 2.7 下慢的根本原因
  • 他们在 Python 3.4 中切换到 SipHash,这在某些数据上比 FNV 慢。见bugs.python.org/issue14621
  • @vaultah:谢谢!将其作为“答案”与参考一起投入,我会给你一个赞成票!匿名:当它运行数十亿次时,你会注意到不同之处。 40% 就是 40%。
  • @ChrisCogdon 我正在回答最后一个问题。哈希不安全。

标签: python python-3.4


【解决方案1】:

hash() 函数在 Python 2.7 和 Python 3.4 之间有两个变化

  1. SipHash 的采用
  2. 默认启用 哈希随机化

参考文献:

【讨论】:

  • 哈希随机化也在至少四年后的每个 2.7 版本中默认启用。此外,这只影响字符串哈希,而 OP 中的示例是整数哈希,不是随机的。
  • @SvenMarnach:“至少五年后,每个 2.7 版本也默认启用哈希随机化” - 呃,什么?你有这方面的参考吗?
  • @user2357112 你是对的,它默认没有启用。它只是在我碰巧经常使用的平台上启用(即使对于 Python 2.7)。无论如何,这仍然与原始帖子中观察到的时间差异无关,因为整数的哈希不是随机的。
  • 请注意,哈希随机化不会使哈希变慢。随机种子在启动时确定一次并包含在哈希中。如果它被禁用,则使用 0 代替。没有速度差异。
  • @SvenMarnach:同意你的看法。那不完全是PYTHONHASHSEED的原因,更新了答案
猜你喜欢
  • 2016-09-08
  • 2018-06-23
  • 2023-04-01
  • 2016-10-04
  • 1970-01-01
  • 2016-06-23
  • 2016-03-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多