【问题标题】:Optimizing Python Dictionary Lookup Speeds by Shortening Key Size?通过缩短密钥大小来优化 Python 字典查找速度?
【发布时间】:2014-12-17 05:46:00
【问题描述】:

我不清楚字典查找的幕后发生了什么。密钥大小是否会影响查找该密钥的速度?

当前字典键的长度在 10-20 之间,由字母数字组成。

我需要每分钟进行数百次查找。

如果我用 1 到 4 位的较小密钥 ID 替换那些,我会获得更快的查找时间吗?这意味着我需要在字典保存的每个项目中添加另一个值。总的来说,字典会更大。

我还需要更改程序以查找 ID,然后获取与 ID 关联的 URL。

我可能只是增加了程序的复杂性而没有什么好处吗?

【问题讨论】:

  • “我需要每分钟进行数百次查找。”。不用担心,数百都不算什么。
  • 您可能没有意识到这一点,但无论您是否明确使用字典,python 通常每分钟都会进行数百次 dict 查找。访问类实例上的属性与访问字典中的键的操作相同,因为 python 在内部使用字典来表示类。

标签: python performance optimization dictionary


【解决方案1】:

字典是哈希表,因此查找键包括:

  • 散列密钥。
  • 将散列减小到表大小。
  • 用结果索引表。
  • 比较查找键和输入键。

通常,这是摊销的常数时间,除此之外你什么都不关心。有两个潜在的问题,但它们并不经常出现。


对密钥进行散列处理在密钥长度上花费线性时间。例如,对于巨大的字符串,这可能是一个问题。但是,如果您查看大多数重要类型的源代码,包括 [str/unicode](https://hg.python.org/cpython/file/default/Objects/unicodeobject.c,您会发现它们第一次缓存了哈希。所以,除非您输入(或随机创建,或其他)一堆字符串以查找一次然后丢弃,这在大多数现实生活中的程序中不太可能成为问题。

除此之外,20 个字符真的很短;您可能每秒可以进行 数百万 次这样的哈希,而不是数百次。

根据我的计算机上的快速测试,散列 20 个随机字母需要 973ns,散列一个 4 位数字需要 94ns,散列一个我已经散列的值需要 77ns。是的,那是纳秒。


同时,“用结果索引表”有点作弊。如果两个不同的键散列到同一个索引会发生什么?然后“比较查找的密钥”将失败,然后……接下来会发生什么? CPython 的实现为此使用了探测。 the source 很好地解释了确切的算法。但是您会注意到,给定真正的病态数据,您最终可能会对每个元素进行线性搜索。这永远不会出现 - 除非有人可以通过明确制作病理数据来攻击您的程序,在这种情况下它肯定会出现。

从 20 个字符的字符串切换到 4 位的数字在这里也无济于事。如果我通过字典冲突为你的系统制作密钥,我不在乎你的实际密钥是什么样子,只关心它们散列到什么。


更一般地说,premature optimization is the root of all evil。这有时被错误地引用以夸大这一点。 Knuth 认为最重要的是找到 3% 的优化很重要的情况,而不是优化总是浪费时间。但无论哪种方式,重点是:如果您事先不知道您的程序在哪里太慢(并且如果您认为您事先知道,那么您通常是错的......),分析它,然后找到让您获得最大收益的部分。优化任意一段代码可能根本没有可衡量的效果。

【讨论】:

    【解决方案2】:

    Python 字典在后台实现为哈希映射。例如,如果哈希函数复杂性取决于密钥长度,则密钥长度可能会对性能产生一些影响。但总的来说,性能影响肯定可以忽略不计。

    所以我想说增加的复杂性几乎没有好处。

    【讨论】:

      猜你喜欢
      • 2012-02-07
      • 2013-06-24
      • 1970-01-01
      • 1970-01-01
      • 2013-09-16
      • 2011-11-24
      • 1970-01-01
      • 2016-07-02
      • 1970-01-01
      相关资源
      最近更新 更多