Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory efficiency: One large dictionary or a dictionary of smaller dictionaries?

I'm writing an application in Python (2.6) that requires me to use a dictionary as a data store.

I am curious as to whether or not it is more memory efficient to have one large dictionary, or to break that down into many (much) smaller dictionaries, then have an "index" dictionary that contains a reference to all the smaller dictionaries.

I know there is a lot of overhead in general with lists and dictionaries. I read somewhere that python internally allocates enough space that the dictionary/list # of items to the power of 2.

I'm new enough to python that I'm not sure if there are other unexpected internal complexities/suprises like that, that is not apparent to the average user that I should take into consideration.

One of the difficulties is knowing how the power of 2 system counts "items"? Is each key:pair counted as 1 item? That's seems important to know because if you have a 100 item monolithic dictionary then space 100^2 items would be allocated. If you have 100 single item dictionaries (1 key:pair) then each dictionary would only be allocation 1^2 (aka no extra allocation)?

Any clearly laid out information would be very helpful!

like image 844
Brandon K Avatar asked Mar 22 '09 18:03

Brandon K


People also ask

Are Dictionaries space efficient?

There's no significant difference between the size of one large dictionary and multiple smaller ones. See below. @tgambin - as I said in the answer, the space efficiency is due to the creation of multiple dicts. OF COURSE there will be additional space required when when you're allocating more objects.

Are Python dictionaries memory efficient?

The Python dictionary implementation consumes a surprisingly small amount of memory. But the space taken by the many int and (in particular) string objects, for reference counts, pre-calculated hash codes etc., is more than you'd think at first.

How much memory does a dictionary use?

This sums up to at least 12 bytes on a 32bit machine and 24 bytes on a 64bit machine. The dictionary starts with 8 empty buckets. This is then resized by doubling the number of entries whenever its capacity is reached.

Which is more efficient list or dictionary Python?

A dictionary is 6.6 times faster than a list when we lookup in 100 items.


2 Answers

If you're using Python, you really shouldn't be worrying about this sort of thing in the first place. Just build your data structure the way it best suits your needs, not the computer's.

This smacks of premature optimization, not performance improvement. Profile your code if something is actually bottlenecking, but until then, just let Python do what it does and focus on the actual programming task, and not the underlying mechanics.

like image 33
Soviut Avatar answered Oct 12 '22 19:10

Soviut


Three suggestions:

  1. Use one dictionary.
    It's easier, it's more straightforward, and someone else has already optimized this problem for you. Until you've actually measured your code and traced a performance problem to this part of it, you have no reason not to do the simple, straightforward thing.

  2. Optimize later.
    If you are really worried about performance, then abstract the problem make a class to wrap whatever lookup mechanism you end up using and write your code to use this class. You can change the implementation later if you find you need some other data structure for greater performance.

  3. Read up on hash tables.
    Dictionaries are hash tables, and if you are worried about their time or space overhead, you should read up on how they're implemented. This is basic computer science. The short of it is that hash tables are:

    • average case O(1) lookup time
    • O(n) space (Expect about 2n, depending on various parameters)

    I do not know where you read that they were O(n^2) space, but if they were, then they would not be in widespread, practical use as they are in most languages today. There are two advantages to these nice properties of hash tables:

    1. O(1) lookup time implies that you will not pay a cost in lookup time for having a larger dictionary, as lookup time doesn't depend on size.
    2. O(n) space implies that you don't gain much of anything from breaking your dictionary up into smaller pieces. Space scales linearly with number of elements, so lots of small dictionaries will not take up significantly less space than one large one or vice versa. This would not be true if they were O(n^2) space, but lucky for you, they're not.

    Here are some more resources that might help:

    • The Wikipedia article on Hash Tables gives a great listing of the various lookup and allocation schemes used in hashtables.
    • The GNU Scheme documentation has a nice discussion of how much space you can expect hashtables to take up, including a formal discussion of why "the amount of space used by the hash table is proportional to the number of associations in the table". This might interest you.

    Here are some things you might consider if you find you actually need to optimize your dictionary implementation:

    • Here is the C source code for Python's dictionaries, in case you want ALL the details. There's copious documentation in here:
      • dictobject.h
      • dictobject.c
    • Here is a python implementation of that, in case you don't like reading C.
      (Thanks to Ben Peterson)
    • The Java Hashtable class docs talk a bit about how load factors work, and how they affect the space your hash takes up. Note there's a tradeoff between your load factor and how frequently you need to rehash. Rehashes can be costly.
like image 130
Todd Gamblin Avatar answered Oct 12 '22 20:10

Todd Gamblin