在Tim Peter's answer中,“有没有理由不使用有序词典”,他说
OrderedDict是dict的子类。
速度并不慢很多,但至少使用普通字典使内存翻倍。
现在,在浏览particular question时,我尝试使用ipython
进行一些示例检查,这两项检查都与之前的推理相矛盾:
dict
和OrderedDict
的大小相同OrderedDict
上操作比在dict
上操作时间大约多7-8倍(因此慢得多)有人可以向我解释我在推理中出错的地方吗?
import sys
import random
from collections import OrderedDict
test_dict = {}
test_ordered_dict = OrderedDict()
for key in range(10000):
test_dict[key] = random.random()
test_ordered_dict[key] = random.random()
sys.getsizeof(test_dict)
786712
sys.getsizeof(test_ordered_dict)
786712
%timeit
检查插入时间:import sys
import random
from collections import OrderedDict
def operate_on_dict(r):
test_dict = {}
for key in range(r):
test_dict[key] = random.random()
def operate_on_ordered_dict(r):
test_ordered_dict = OrderedDict()
for key in range(r):
test_ordered_dict[key] = random.random()
%timeit for x in range(100): operate_on_ordered_dict(100)
100 loops, best of 3: 9.24 ms per loop
%timeit for x in range(100): operate_on_dict(100)
1000 loops, best of 3: 1.23 ms per loop
答案 0 :(得分:10)
我认为尺寸问题是因为Python 2.X implementation of OrderedDict
中没有定义__sizeof__
方法,所以它简单地回退到dict的__sizeof__
方法。 / p>
为了在此处证明这一点,我在此处创建了一个A
类,其中list
扩展了foo
并添加了另一个方法class A(list):
def __getitem__(self, k):
return list.__getitem__(self, k)
def foo(self):
print 'abcde'
>>> a = A(range(1000))
>>> b = list(range(1000))
来检查是否会影响大小。
sys.getsizeof
但>>> sys.getsizeof(a), sys.getsizeof(b)
(9120, 9120)
仍然返回相同的尺寸:
A
当然>>> %%timeit
... for _ in xrange(1000):
... a[_]
...
1000 loops, best of 3: 449 µs per loop
>>> %%timeit
for _ in xrange(1000):
b[_]
...
10000 loops, best of 3: 52 µs per loop
会变慢,因为它的方法在Python中运行而list的方法将在纯C中运行。
def __sizeof__(self):
sizeof = _sys.getsizeof
n = len(self) + 1 # number of links including root
size = sizeof(self.__dict__) # instance dictionary
size += sizeof(self.__map) * 2 # internal dict and inherited dict
size += sizeof(self.__hardroot) * n # link objects
size += sizeof(self.__root) * n # proxy objects
return size
这似乎在Python 3中得到修复,现在有一个定义良好的__sizeof__
方法:
{{1}}