我注意到,在许多情况下,从嵌套字典中检索数据要比使用元组键的字典快得多。这似乎与所说的here相矛盾。任何人都可以解释是什么原因造成的我的问题是,更快的方式似乎不那么“pythonic”,并且可能导致巨大丑陋的嵌套字典(例如a_dict [a] [b] [c] [d]而不是a_dict [a,b,c,d])。 / p>
下面是使用整数作为键时发生这种情况的示例:
使用元组:
print timeit.timeit('''
for (int1, int2) in indexes:
x[ int1, int2 ]
''', setup='''
x={}
indexes = []
for int1 in xrange(1000):
for int2 in xrange(1000):
x[ int1, int2 ] = 'asd'
indexes.append((int1, int2))
''', number = 100)
使用嵌套字典:
print timeit.timeit('''
for (int1, int2) in indexes:
x[int1][ int2 ]
''', setup='''
x={}
indexes = []
for int1 in xrange(1000):
x[int1] = {}
for int2 in xrange(1000):
x[ int1 ][int2] = 'asd'
indexes.append((int1, int2))
''', number = 100)
结果:
36.8627537348
12.2223380257
我认为这是一个非常重大的差异。
答案 0 :(得分:2)
首先,你所做的两个评估并不完全正确。在第一种情况下,您要解压缩密钥然后重新打包以获取值。
我得到的时间是:
In [3]: timeit.timeit('''
...: for key in indexes:
...: x[key]
...: ''', setup='''
...: x={}
...: indexes = []
...: for a in range(1000):
...: for b in range(1000):
...: x[a,b] = 'asd'
...: indexes.append((a, b))
...: ''', number=100)
Out[3]: 28.43928542699996
In [5]: timeit.timeit('''
...: for key in indexes:
...: a,b = key
...: x[a][b]
...: ''', setup='''
...: x={}
...: indexes = []
...: for a in range(1000):
...: x[a] = {}
...: for b in range(1000):
...: x[a][b] = 'asd'
...: indexes.append((a, b))
...: ''', number=100)
Out[5]: 10.23602621900045
(使用python3.3),差异已经有点小了。你的基准测试显示差异为3倍,差异为2.78倍。
性能上的差异是由于:
元组需要更多时间来散列。实际上整数散列为自己(hash(1) -> 1
),因此它们需要最少的时间来散列,元组必须计算所有元素的散列和将它们连接在一起。
每次访问字典键时,字典都必须检查键的相等性,并且比较元组比比较整数要慢。
我想指出你的基准没有多大意义。为什么要将所有密钥存储在列表中?请注意,使用元组键可以简单地遍历字典,而在嵌套的情况下,您必须使用嵌套循环。 嵌套字典也可能会占用更多内存。
在使用高度嵌套的字典之前,您必须确保字典访问是瓶颈。我怀疑它会成为瓶颈,特别是除了访问/存储词典中的项目之外你还做其他任何事情。
嵌套序列往往难以处理,并且您经常需要嵌套循环来处理它们,这意味着更多的代码和更少的可维护代码。
答案 1 :(得分:0)
似乎散列元组有点贵。不仅仅是创建一个新的dict并在insert上执行整数锁定。