【问题标题】:Two-dimensional vs. One-dimensional dictionary efficiency in PythonPython中的二维与一维字典效率
【发布时间】:2012-04-28 07:08:17
【问题描述】:

在内存和速度方面哪个更有效

d[(first,second)]

d[first][second],

其中d 是元组或字典的字典?

【问题讨论】:

  • 第一个是one字典,第二个是two。内存方面,两个字典可能会消耗更多内存 - 但话又说回来,这完全取决于您的应用数据配置文件。
  • 我认为这里的答案是几乎可以忽略不计。这里真正的问题应该是:对于使用它的代码的读者/作者来说,什么更有用?.
  • miku 的声明“第一个[语句]是一个字典,第二个[语句]是两个。”不完全正确。第二条语句d[a][b]实际上是N+1个字典,其中N是a的唯一值个数。
  • 性能在这里是最重要的,因为对更快执行的需求大大超过了对代码质量/可读性的需求。

标签: python performance dictionary nested tuples


【解决方案1】:

这里有一些非常基本的测试数据表明,对于一个非常人为的示例(使用数字作为键存储“a”一百万次)使用 2 个字典要快得多。

$ python -m timeit 'd = {i:{j:"a" for j in range(1000)} for i in range(1000)};a = [d[i][j] for j in range(1000) for i in range(1000)];'
10 loops, best of 3: 316 msec per loop
$ python -m timeit 'd = {(i, j):"a" for j in range(1000) for i in range(1000)};a = [d[i, j] for j in range(1000) for i in range(1000)];'
10 loops, best of 3: 970 msec per loop

当然,这些测试并不一定意味着任何事情,具体取决于您要执行的操作。确定要存储的内容,然后进行测试。

更多数据:

$ python -m timeit 'a = [(hash(i), hash(j)) for i in range(1000) for j in range(1000)]'
10 loops, best of 3: 304 msec per loop
$ python -m timeit 'a = [hash((i, j)) for i in range(1000) for j in range(1000)]'
10 loops, best of 3: 172 msec per loop
$ python -m timeit 'd = {i:{j:"a" for j in range(1000)} for i in range(1000)}'
10 loops, best of 3: 101 msec per loop
$ python -m timeit 'd = {(i, j):"a" for j in range(1000) for i in range(1000)}'
10 loops, best of 3: 645 msec per loop

再一次,这显然 表示现实世界的使用,但在我看来,用这样的元组构建字典的成本是 巨大的,这就是字典中的字典胜出。这让我感到惊讶,我期待完全不同的结果。有时间我会多尝试一些。

【讨论】:

  • 有趣。我的猜测是,不同之处在于散列 tuple? 所需的时间增加了
  • @agf 发布了更多数据,我真的不确定为什么差异如此之大。使用元组构建 dict 的成本要高得多,但散列元组实际上 更快? 我使用的是非常粗略的方法,所以我可能读得太深了,但我还是有点困惑.
  • 我想知道在构建二维字典时单独循环值是否可以让您缓存更多。这似乎是一个潜在的解释。
  • "请注意,(在实践中)仅处理 str 键的 dicts 有一条快速路径;这不会影响算法复杂性,但会显着影响常数因素:多快一个典型的程序完成。” Source 也可能会影响这一点。
【解决方案2】:

有点令人惊讶的是,字典的字典比 CPython 2.7 和 Pypy 1.8 中的元组更快。

我没有检查空间,但你可以用 ps 做到这一点。

【讨论】:

  • 字典是哈希表,对吧?所以它们当然很快,但它们占用了大量空间。
  • 什么更快?直观地说,我希望插入字典字典的速度会慢一些,因为您经常需要初始化一个新字典(如果您使用的是新的第一个键)。但是,我希望访问速度更快,因为碰撞会减少一个数量级。请提供代码,以便我们查看您实际进行的基准测试。
猜你喜欢
  • 2018-07-20
  • 1970-01-01
  • 2014-11-13
  • 2011-08-03
  • 1970-01-01
  • 1970-01-01
  • 2019-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多