我已经创建了大量的dicts(数百万个条目),我注意到如果我按顺序创建它们,速度会更快。在
我想这与hash函数的冲突有关,但是有人能解释一下为什么会发生这种情况,以及python版本之间是否一致?在
这里有一个人为的例子:
import timeit
import random
def get_test_data(num, size):
olist, ulist = [], []
for _ in range(num):
otest = [str(i) for i in range(size)]
utest = list(otest)
random.shuffle(utest)
olist.append(otest)
ulist.append(utest)
return olist, ulist
NUM_TESTS = 20
# Precalculate the test data so we only measure dict creation time
ordered, unordered = get_test_data(NUM_TESTS, 1000000)
def test_ordered():
dict((k, k) for k in ordered.pop())
def test_unordered():
dict((k, k) for k in unordered.pop())
print "unordered: ",
print timeit.timeit("test_unordered()",
setup="from __main__ import test_unordered, test_ordered",
number=NUM_TESTS)
print "ordered: ",
print timeit.timeit("test_ordered()",
setup="from __main__ import test_unordered, test_ordered",
number=NUM_TESTS)
我的机器的输出始终是:
^{pr2}$我在UbuntuPrecise x86\u64中使用Python2.7.3
我几乎可以肯定的是:当您第一次创建
otest
时,字符串按顺序存储在内存中。当您创建utest
时,字符串指向相同的内存缓冲区,只是现在这些位置无序,这会影响无序测试用例的缓存性能。在这是证据。我已将您的
get_test_data
函数替换为以下版本:我现在在内存中连续地构造
ulist
中的字符串,然后通过用适当的键对这些字符串排序来构建olist
。在我的机器上,这会反转两个测试的运行时间。在检查source code of the python dict可以看到连续的字符串或整数产生的冲突较少。这结合@skishhore关于更好的缓存本地性的评论可能是答案。在
相关问题 更多 >
编程相关推荐