4

I'm making a chess engine and for my piece square tables i can use lists or dictionaries. As the implementation of the piece square tables made the engine two times slower, i was wondering if i use the wrong data structure. I'm using lists, but am wondering if dictionaries might be a better idea?

List example:

list_ex = [50, 30, 30, 30
           20, 30, 50, 40]
call = list_ex[2]

Dictionary example:

dict_ex = {0: 50, 1: 30, 2: 30, 3: 30,
           4: 20, 5: 30, 6: 50, 7: 40}
call = dict_ex[2]

as you can see, i always know the index, i just need to return the value associated with that index. Which data structure would be faster for this, dictionaries or lists?

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
stensootla
  • 13,945
  • 9
  • 45
  • 68

4 Answers4

6

As you can see in the python wiki on TimeComplexity, list and dict they both have the same complexity in the average case on getting an item of O(1). So there should be not that much of a difference for simple index based look-ups.

EDIT: I just wrote a little benchmarking code that gets the first element, one from the center and the last. You see that a list has a small advance (although a deviation of 0.01s is not that large when considering that the code runs 1000000 times).

In summary I would use a list if I were in your situation, as it also fits better to the problem of an index based request.

>>> from timeit import Timer
>>> t=Timer("(l[0], l[3], l[7])","l=[50, 30, 30, 30, 20, 30, 50, 40]")
>>> sorted(t.repeat(5))
[0.17861513267149576, 0.17863279532627985, 0.17883092423682, 0.17892576501373014, 0.18901037296996037]
>>> t=Timer("(l[0], l[3], l[7])","l={0: 50, 1: 30, 2: 30, 3: 30, 4: 20, 5: 30, 6: 50, 7: 40}")
>>> sorted(t.repeat(5))
[0.18541179903735383, 0.1855488765975224, 0.1855757545505412, 0.18578041096390052, 0.21753940019925722]
halex
  • 16,253
  • 5
  • 58
  • 67
  • Thank you. I'll stick to my original data structure (lists) then. – stensootla Oct 09 '12 at 06:23
  • You are also timing tuple creation. – Steven Rumbalski Oct 09 '12 at 06:41
  • @StevenRumbalski I admit that the absolute times I measure are not meaningful to reason about the time it needs to get one element but I'm interested which of the two ways are faster and so I time the tuple creation both times so if I make the difference between the times I add significance and the creation time for the tuples vanishes. – halex Oct 09 '12 at 07:53
  • 1
    @halex: Just don't create tuples. Instead of `"(l[0], l[3], l[7])"`, do `"l[0];l[1];l[2];l[3];l[4];l[5];l[6];l[7]"`. The semicolons separate statements. With these changes, lists show as 25% faster on my system. (I also changed the test to access every element to capture best and worst case scenarios.) – Steven Rumbalski Oct 09 '12 at 16:26
3

You are better off using a list than a dict in terms of lookup speed. Tuple is even a bit faster.

timeit dict_ex[2]
10000000 loops, best of 3: 148 ns per loop

timeit list_ex[2]
10000000 loops, best of 3: 116 ns per loop

tuple_ex=tuple(list_ex)

timeit tuple_ex[2]
10000000 loops, best of 3: 112 ns per loop
root
  • 76,608
  • 25
  • 108
  • 120
2

You can easily benchmark this with the timeit module (python -m timeit -S "setup" -- "statement"). But in this case, I can tell you dictionaries won't beat lists, because list lookup is trivial in comparison to dict lookup. Both will be fast, independent from the key and the number of items in the collection, but list will win on micro benchmarks. Of course, this shouldn't rule your decision. Go for clarity, optimize algorithms instead of insignificant details, premature optimization, etc. ad nauseam.

But I'd still say a list is more appropriate, both semantically (you don't have a free-form mapping, you have a sequence), and for preventing errors (by rejecting out of range and non-integer indices).

0

Python in general is going to be slow for something like this.

Take a look at this other SO question, the first answer.

I'd say your best bet here is tuples first if your object can be immutable. If not, then stick with lists. Either way, there isn't going to be a huge difference between list and dict.

I see that halex has also just answered, and seems to agree.

Community
  • 1
  • 1
jdotjdot
  • 16,134
  • 13
  • 66
  • 118
  • A set is completely wrong here, as order and duplicates matter. –  Oct 09 '12 at 06:20
  • @delnan, sorry, you're completely right. Wrong word, let me fix that. There we go. Meant to write `tuple`. Good catch. Also, if you were the downvote and made it because of `set`, I'd appreciate it if you would remove the downvote. Was simply a Freudian slip. – jdotjdot Oct 09 '12 at 06:21