列表和字典之间的Python __getitem__性能

问题描述

我已经实现了动态编程算法(自下而上)。
作为快速解决方案,我为DP表使用了字典而不是固定大小的数组,但是考虑到我的输入大小( n 最多为50k, m 最多为100),我认为将dp_table: Dict[int,Dict[int,float]]重构为dp_table: List[List[float]]有很多好处。

我们知道哈希表具有用于索引的运行时间O(1),但常量值为“高”,而列表索引为O(1),其常量要小得多。

dict.__getitem__list.__getitem__间的性能差异是什么?
使用numpy数组还能获得更多收益吗?

解决方法

使用timeit进行基准测试非常简单。

>>> timeit.Timer('values[50]','values = {i: i for i in range(100)}').timeit(number = 10**7)
0.3076519769999999
>>> timeit.Timer('values[50]','values = list(range(100))').timeit(number = 10**7)
0.2913365720000005
>>> timeit.Timer('values[50]','import numpy; values = numpy.arange(100)').timeit(number = 10**7)
1.262765399000001

奇怪的是,这里的numpy数组执行得很糟糕。

,

dict.__getitem__list.__getitem__之间的性能差异是什么?

wiki.python article TimeComplexity声称具有以下时间复杂性:

  • for list获取项目:平均情况O(1)摊销最差情况O(1)
  • for dict获取项目:平均情况O(1)摊销最坏情况O(n)

请记住,这些是CPython的值,其他python实现可能会有所不同。