Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is OrderedDict() ~10x slower than dict() and list()?

Just run the tests below and noticed that filling an OrderedDict() is roughly an order of magnitude slower than filling a dict() or a list().

Why?

# list()
In [1]: timeit test_list()
1000 loops, best of 3: 298 us per loop

# dict()    
In [3]: timeit test_dict()
1000 loops, best of 3: 269 us per loop

# dict()    
In [3]: timeit test_ord_dict()                                                  
100 loops, best of 3: 1.77 ms per loop

with:

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
like image 426
Amelio Vazquez-Reina Avatar asked Aug 24 '13 20:08

Amelio Vazquez-Reina


People also ask

Is OrderedDict slower than dict?

As you see in the output, operations on dict objects are faster than operations on OrderedDict objects.

What is the difference between OrderedDict and dict?

The OrderedDict is a subclass of dict object in Python. The only difference between OrderedDict and dict is that, in OrderedDict, it maintains the orders of keys as inserted. In the dict, the ordering may or may not be happen. The OrderedDict is a standard library class, which is located in the collections module.

Is OrderedDict deprecated?

No it won't become redundant in Python 3.7 because OrderedDict is not just a dict that retains insertion order, it also offers an order dependent method, OrderedDict. move_to_end() , and supports reversed() iteration*.

What is ordered dictionary?

An OrderedDict is a dictionary subclass that remembers the order in which its contents are added, supporting the usual dict methods. If a new entry overwrites an existing entry, the original insertion position is left unchanged. Deleting an entry and reinserting it will move it to the end.


2 Answers

OrderedDict is implemented in pure Python, so here's the relevant part of the source:

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)

If the key doesn't exist, you'll be creating a new list and accessing two items from a list, which will slow things down.

like image 120
Blender Avatar answered Nov 05 '22 05:11

Blender


Two reasons:

  1. An OrderedDict, by definition, has to do more work than a dict.

  2. (much more importantly) OrderedDict is written in Python, while dict and list are written in C.

like image 20
Zero Piraeus Avatar answered Nov 05 '22 04:11

Zero Piraeus