<div dir="ltr">The docs don't seem to make any guarantee about calling __eq__ or __hash__:<br><br>d[key]<br>Return the item of d with key key. Raises a KeyError if key is not in the map.<br><br>which seems to indicate that this kind of optimization should be fine.<br>
<br>In fact I would very much like messing with the semantics of __eq__ be discouraged in the docs.  Currently, the docs merely say "The truth of x==y does not imply that x!=y is false."  Of course, once __eq__ and __ne__ are separately overridable nothing can be guaranteed but I've seen code where x == y and x != y do completely different things and that was not pretty.<br>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">2014-03-18 21:27 GMT-07:00 Nick Coghlan <span dir="ltr"><<a href="mailto:ncoghlan@gmail.com" target="_blank">ncoghlan@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="">On 19 March 2014 11:09, Steven D'Aprano <<a href="mailto:steve@pearwood.info">steve@pearwood.info</a>> wrote:<br>
> Although I have tentatively said I think this is okay, it is a change in<br>
> actual semantics of Python code: what you write is no longer what gets<br>
> run. That makes this *very* different from changing the implementation<br>
> of sort -- by analogy, its more like changing the semantics of<br>
><br>
>     a = f(x) + f(x)<br>
><br>
> to only call f(x) once. I don't think you would call that an<br>
> implementation detail, would you? Even if justified -- f(x) is a pure,<br>
> deterministic function with no side-effects -- it would still be a<br>
> change to the high-level behaviour of the code.<br>
<br>
</div>Ah, I think this is a good alternative example. Given the stated<br>
assumptions (true builtin dict, not modified between operations),<br>
would we be OK with PyPI optimising the following to only do a single<br>
dict lookup:<br>
<br>
    a = d[x] + d[x]<br>
<br>
It's essentially the same optimisation as the one being discussed - in<br>
the code *as written*, there are two lookups visible, but for any<br>
sensible __hash__ and __eq__ implementation, they should always give<br>
the same answer for a true builtin dict that isn't modified between<br>
the two lookups. (and yes, PyPy has the infrastructure to enforce<br>
those constraints safely and fall back to normal execution if they<br>
aren't met - that ability to take opportunistic advantage of known<br>
behaviours of particular types is one of the key things that makes it<br>
such a powerful tool for implicit optimisations, as compared to things<br>
like Cython and Numba, which change semantics more markedly, but also<br>
have to be explicitly applied to specific sections of your code rather<br>
than being applied automatically).<br>
<br>
I think it's certainly borderline (it's the kind of surprising<br>
behavioural change that irritates people about C/C++ optimisers), but<br>
I also think it's a defensible optimisation if the gain is significant<br>
enough.<br>
<br>
Regards,<br>
<div class="im HOEnZb">Nick.<br>
<br>
--<br>
Nick Coghlan   |   <a href="mailto:ncoghlan@gmail.com">ncoghlan@gmail.com</a>   |   Brisbane, Australia<br>
</div><div class="HOEnZb"><div class="h5">_______________________________________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" target="_blank">https://mail.python.org/mailman/listinfo/python-dev</a><br>
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/antony.lee%40berkeley.edu" target="_blank">https://mail.python.org/mailman/options/python-dev/antony.lee%40berkeley.edu</a><br>
</div></div></blockquote></div><br></div>