[Python-Dev] Intricacies of calling __eq__
Nick Coghlan
ncoghlan at gmail.com
Tue Mar 18 10:35:15 CET 2014
On 18 March 2014 17:52, Maciej Fijalkowski <fijall at gmail.com> wrote:
> Hi
>
> I have a question about calling __eq__ in some cases.
>
> We're thinking about doing an optimization where say:
>
> if x in d:
> return d[x]
>
> where d is a dict would result in only one dict lookup (the second one
> being constant folded away). The question is whether it's ok to do it,
> despite the fact that it changes the semantics on how many times
> __eq__ is called on x.
I'll assume the following hold:
- we're only talking about true builtin dicts (the similarity between
__contains__ and __getitem__ can't be assumed otherwise)
- guards will trigger if d is mutated (e.g. by another thread) between
the containment check and the item retrieval
Semantically, what you propose is roughly equivalent to reinterpreting
the look-before-you-leap version to the exception handling based
fallback:
try:
return d[x]
except KeyError:
pass
For a builtin dict and any *reasonable* x, those two operations will
behave the same way. Differences arise only if x.__hash__ or x.__eq__
is defined in a way that most people would consider unreasonable.
For an optimisation that actually changes the language semantics like
that, though, I would expect it to be buying a significant payoff in
speed, especially given that most cases where the key lookup is known
to be a bottleneck can already be optimised by hand.
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
More information about the Python-Dev
mailing list