how fast is Python code - another detail

vincent wehren vincent at visualtrans.de
Thu Mar 4 15:18:15 EST 2004


----- Original Message ----- 
From: "Gregor Lingl" <glingl at aon.at>
Newsgroups: comp.lang.python
Sent: Thursday, March 04, 2004 7:43 PM
Subject: how fast is Python code - another detail


> "Quality of design" may - for instance - consist
> in deleting 7 characters:
>
> Today I made - by accident - an interesting
> observation. The following is a snippet from
> a program which computes anagrams from a wordlist:
>
> def find_anagrams(wordlist):
>      d = {}
>      for word in wordlist:
> sig = anagram_signature(word)
> if sig not in d:
>              d[sig] = []     # d.setdefault intentionally not used
>      return d
>
> On my machine it computes d
> for a wordlist of 10000 items in less than 0.13s
> and for a wordlist of 20000 items in less than 0.25s
>
> Today one of my students inadvertedly wrote in the fifth line
>
>          if sig not in d.keys():
>
> and now timing of find_anagrams had the following results:
>
> for a wordlist of 10000 items approx. 9.33s, i.e a factor
> of approx 65 slower
>
> and for a wordlist of 20000 items approx. 60s, i.e. a factor
> of approx 250 slower. (!!!) (Imagine that the full wordlist
> in this example has 45000 entires, so an additional factor of
> 16 applies ...)
>
> I think this is a very astonishing and relevant difference!
> I think I understand why it is the case - the timing factor
> is proportional to the square of len(wordlist), because
> in every loop a list d.keys() has to be computed and now
> this has to be used for searching for the key sig,
> while for sig in d uses some built-in generator-property
> of dictionaries ...  (?)
>
> *on_the_other_ hand* I thought, that those two idioms
> are semantically identical.

Nope. They are not. "if sig not in d" equates to "not d.has_key(sig)"
("O(1)" in terms of performance)
And d.keys() makes a copy of d's entire list of keys (giving you "O(N)").

You might also consider using:

try:
   d[sig]
except KeyError:
   d[sig]=[]

HTH,

Vincent Wehren

So my question: why does the
> Python interpreter not recognize this identity and internally
> replace the latter by the first in order to get *much*
> better performance? >
> - would this lead to wrong results in some cases?
> - or would it be too difficult to implement?
> - or is this considered a problem of minor importance?
> - or was it only forgotten to do?
> - or what else?


> Regards,
> Gregor
>
> P.S.: Or was the key in dict idiom introduced exactly
> inorder to solve this problem?





More information about the Python-list mailing list