[MERGE] remove has_key() usage
Andrew Bennetts
andrew at canonical.com
Wed Aug 30 04:35:37 BST 2006
On Tue, Aug 29, 2006 at 02:50:11PM -0700, Brian Harring wrote:
[...]
>
> 1) slightly faster
> $ python -m timeit -s 'd=dict([(x,None) for x in xrange(1000)]);' 'd.has_key(500)'
> 1000000 loops, best of 3: 1.48 usec per loop
> $ python -m timeit -s 'd=dict([(x,None) for x in xrange(1000)]);' '500 in d'
> 1000000 loops, best of 3: 1.02 usec per loop
>
> Why that's faster, as far as I know it comes down to the fact the
> interpretter does the __contains__ getattr rather then the python code
> triggering it itself; might just be that it is less opcodes; either
> way, consistantly faster in my experience.
In general, operators are faster than methods. This is particularly true of
types implemented in C, iirc. The interpreter can go straight to the slot of
the object where the operator is implemented, rather than needing to do a
getattr (and thus at least one dict lookup). Some operators have special case
fast paths in the bytecode eval loop (e.g. for int addition).
> 2) it relies on the general containment protocol rather then a dict
> specific method; code can work with any sequence without having to be
> changed if it relies on __contains__ instead of the dict specific
> containment method.
That's a good reason too. In my opinion there's another reason to prefer 'in':
3) "if x in y:" is slightly more readable than "if y.has_key(x):".
-Andrew.
More information about the bazaar
mailing list