Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么OrderedDict()比dict()和list()慢10倍?_Python_Python 2.x - Fatal编程技术网

Python 为什么OrderedDict()比dict()和list()慢10倍?

Python 为什么OrderedDict()比dict()和list()慢10倍?,python,python-2.x,Python,Python 2.x,只需运行下面的测试,并注意到填充一个orderedict()大约比填充一个dict()或list()慢一个数量级 为什么? 与: OrderedDict是用纯Python实现的,因此下面是源代码的相关部分: def __setitem__(self, key, value, dict_setitem=dict.__setitem__): 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a

只需运行下面的测试,并注意到填充一个
orderedict()
大约比填充一个
dict()
list()
慢一个数量级

为什么?

与:


OrderedDict
是用纯Python实现的,因此下面是源代码的相关部分:

def __setitem__(self, key, value, dict_setitem=dict.__setitem__):
    'od.__setitem__(i, y) <==> od[i]=y'
    # Setting a new item creates a new link at the end of the linked list,
    # and the inherited dictionary is updated with the new key/value pair.
    if key not in self:
        root = self.__root
        last = root[0]
        last[1] = root[0] = self.__map[key] = [last, root, key]
    return dict_setitem(self, key, value)
def\uuuuu setitem\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
'od.\uuuu集合项\uuuu(i,y)od[i]=y'
#设置新项目将在链接列表的末尾创建新链接,
#继承的字典将使用新的键/值对进行更新。
如果键不在self中:
根=自身
last=根[0]
最后[1]=根[0]=自身。\u映射[键]=[最后,根,键]
返回dict_setitem(self、key、value)
如果密钥不存在,您将创建一个新列表并访问列表中的两个项目,这将减慢速度。

两个原因:

  • 根据定义,
    OrderedDict
    dict
    要做更多的工作

  • (更重要的是)
    OrderedDict
    是,而和是用C编写的


  • 第一个我不太确定。它当然提供了一个额外的保证,但是完全针对这些保证的实现不应该导致显著的额外工作(另请参见:几个月前的一个python开发人员或python ideas线程关于dict的更改,该更改在许多情况下会自动保持顺序,并在其他情况下更容易维护)。当然不足以慢一个数量级。@delnan我同意#2比#1重要得多。我还没有研究过
    orderedict
    的代码,但如果在行为上尽可能接近
    dict
    比在执行上更仔细,我也不会感到惊讶;这至少是Python中的典型方法。@ZeroPiraeus许多非基本类型也有C实现,例如
    deque
    defaultdict
    (保持在
    collections
    )中。python3中的速度差发生了变化,现在OrderedDict只是有点慢,以防有人发现这个问题,只是想有一个保留插入顺序的dict-您不再需要使用OrderedDict。由于Python 3.7,该语言现在需要dict来保留插入顺序
    https://mail.python.org/pipermail/python-dev/2017-December/151283.html
    。谢谢@user136036 True。时光飞逝。
    def test_ord_dict():
      a = OrderedDict()
      for el in xrange(1000):
        a[el] = np.random.randint(100)
      return a
    
    def test_dict():
      a = dict()
      for el in xrange(1000):
        a[el] = np.random.randint(100)
      return a
    
    def test_list():
      a = list()
      for el in xrange(1000):
        a.append(np.random.randint(100))
      return a
    
    def __setitem__(self, key, value, dict_setitem=dict.__setitem__):
        'od.__setitem__(i, y) <==> od[i]=y'
        # Setting a new item creates a new link at the end of the linked list,
        # and the inherited dictionary is updated with the new key/value pair.
        if key not in self:
            root = self.__root
            last = root[0]
            last[1] = root[0] = self.__map[key] = [last, root, key]
        return dict_setitem(self, key, value)