【问题标题】:Naming dict keys for fast lookup in python命名dict键以在python中快速查找
【发布时间】:2011-09-15 13:05:16
【问题描述】:

我将有 1 个小字典(在 5 到 20 个键之间),在 python 2.5 中,一页加载最多会引用一百次左右。

我开始命名它将查找的键,我想知道是否有我可以遵循的键命名约定来帮助 dict 查找时间。

【问题讨论】:

  • 如果你可以使用整数键——它们会比字符串快。 (如果是这样,您可能只使用一个列表。)
  • @Sven Marnach,是这样吗?哈希函数对整数的调用是否比对字符串的调用更快?如果是这样的信息很有趣,你有参考吗?
  • @juanchopanza:整数对自己进行哈希(至少在用于哈希值的整数类型范围内)。字符串必须至少迭代一次。
  • @juanchopanza:对于短字符串,差异可能可以忽略不计,但列表会更快。

标签: python django performance dictionary


【解决方案1】:

因为 Python 字符串哈希函数会遍历字符(至少在 this 仍然适用的情况下),我会选择 short 字符串。

【讨论】:

  • 它确实缓存了它们,请参阅stringobject.c 中的 string_hash(PyStringObject *a)。从那以后它可能一直如此。考虑到该页面仅给出了用 Python 编写的算法的概念,而不是确切的实现。
  • @delnan:感谢您提供的信息,我并不真正了解 Python 内部结构。但由于哈希无论如何都必须至少计算一次,因此以简化的形式它仍然适用。我相应地进行了编辑。
  • 这是一个非常严格的循环,只执行由现代编译器编译的 C 语言编写的数字运算。平均迭代不太可能花费超过几个周期。这是您无法测量任何差异的级别,除非您运行一百万个循环,每个循环有一百万次迭代。剃掉一个字符可能只会产生几纳秒的差异。 完全。我不认为这是一个合理的建议。
【解决方案2】:

可能对它们来说是合理的名称,恰好会产生哈希不冲突的名称。然而,CPython dicts 已经是已知宇宙中最优化的数据结构之一,对大多数输入产生很少的冲突,与其他内置类型的哈希方案配合良好,解决冲突非常快,等等。非常 em> 即使您找到了一些东西,您也不太可能看到任何好处,尤其是因为一百次查找并没有那么多。

例如,在我使用了 4 年的台式机上运行的 timeit 基准测试(运行一个可笑的低预算双核 CPU,频率为 3.1 GHz):

...>python -mtimeit --setup="d = {chr(i)*100: i for i in range(15)};\
k = chr(7)*100" "d[k]"

1000000 loops, best of 3: 0.222 usec per loop

这些字符串比手动输入变量名的所有字符串大十倍。将长度从 100 减少到 10 会导致每次查找 0.0778 微秒。现在测量页面的加载速度并进行比较(或者,只需考虑构建页面时您实际所做的工作需要多长时间);并考虑缓存、框架开销以及所有这些因素。

您在这方面所做的任何事情都不会对性能、周期、句号产生影响。

【讨论】:

    【解决方案3】:

    Python 字典有一个字符串键的快速路径,所以使用这些(而不是,比如说,元组)。字符串的哈希值缓存在该字符串中,因此字符串保持与实际值相同更为重要;字符串常量(即在程序中逐字出现的字符串,不是计算的结果)始终保持完全相同,因此只要您使用它们,就无需担心。

    【讨论】:

      【解决方案4】:

      添加另一个方面:

      对于非常小的字典和繁重的时间限制,计算散列的时间可能只是总时间的一小部分。因此,对于(比如说)5 个元素,使用数组和顺序搜索(当然,包装到一些 MiniDictionary 对象中)可能会更快,甚至可能通过二分搜索来增强。这可能会找到具有 2-3 次比较的元素,这可能会也可能不会比哈希计算加一次比较快。

      收支平衡取决于哈希速度、平均元素数量和预期的哈希冲突次数,因此需要进行一些测量,并且没有“一刀切”的答案。

      【讨论】:

      • 如果搜索是用 Python 编写的,则不会。
      【解决方案5】:

      我必须测试 ;-)

      使用

      • f1,整数键1
      • f2 短字符串,"one"
      • f3 长字符串"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

      作为长度为 4 的字典的键之一。迭代 10,000,000 次并测量时间。我得到了这个结果:

      <function f1 at 0xb779187c>
      f1 3.64
      <function f2 at 0xb7791bfc>
      f2 3.48
      <function f3 at 0xb7791bc4>
      f3 3.65
      

      没有区别……

      我的code

      【讨论】:

      • 所以基本上我正在收集...别担心,尤其是对于这么小的字典和相对较少的查找次数。
      猜你喜欢
      • 1970-01-01
      • 2010-12-20
      • 1970-01-01
      • 2022-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多