<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Mon, 1 Feb 2016 at 11:51 Yury Selivanov <<a href="mailto:yselivanov.ml@gmail.com">yselivanov.ml@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Brett,<br>
<br>
On 2016-02-01 2:30 PM, Brett Cannon wrote:<br>
><br>
><br>
> On Mon, 1 Feb 2016 at 11:11 Yury Selivanov <<a href="mailto:yselivanov.ml@gmail.com" target="_blank">yselivanov.ml@gmail.com</a><br>
> <mailto:<a href="mailto:yselivanov.ml@gmail.com" target="_blank">yselivanov.ml@gmail.com</a>>> wrote:<br>
><br>
>     Hi,<br>
><br>
[..]<br>
><br>
>     What's next?<br>
>     ------------<br>
><br>
>     First, I'd like to merge the new LOAD_METHOD opcode, see issue 26110<br>
>     [1].  It's a very straightforward optimization, the patch is small and<br>
>     easy to review.<br>
><br>
><br>
> +1 from me.<br>
><br>
><br>
>     Second, I'd like to merge the new opcode cache, see issue 26219 [5].<br>
>     All unittests pass.  Memory usage increase is very moderate (<1mb for<br>
>     the entire test suite), and the performance increase is significant.<br>
>     The only potential blocker for this is PEP 509 approval (which I'd be<br>
>     happy to assist with).<br>
><br>
><br>
> I think the fact that it improves performance across the board as well<br>
> as eliminates the various tricks people use to cache global and<br>
> built-ins, a big +1 from me. I guess that means Victor needs to ask<br>
> for pronouncement on PEP 509.<br>
<br>
Great!  AFAIK Victor still needs to update the PEP with some changes<br>
(globally unique ma_version).  My patch includes the latest<br>
implementation of PEP 509, and it works fine (no regressions, no broken<br>
unittests).  I can also assist with reviewing Victor's implementation if<br>
the PEP is accepted.<br>
<br>
><br>
> BTW, where does LOAD_ATTR fit into all of this?<br>
<br>
LOAD_ATTR optimization doesn't use any of PEP 509 new stuff (if I<br>
understand you question correctly).  It's based on the following<br>
assumptions (that really make JITs work so well):<br>
<br>
1. Most classes don't implement __getattribute__.<br>
<br>
2. A lot of attributes are stored in objects' __dict__s.<br>
<br>
3. Most attributes aren't shaded by descriptors/getters-setters; most<br>
code just uses "self.attr".<br>
<br>
4. An average method/function works on objects of the same type. Which<br>
means that those objects were constructed in a very similar (if not<br>
exact) fashion.<br>
<br>
For instance:<br>
<br>
class F:<br>
    def __init__(self, name):<br>
        <a href="http://self.name" rel="noreferrer" target="_blank">self.name</a> = name<br>
    def say(self):<br>
        print(<a href="http://self.name" rel="noreferrer" target="_blank">self.name</a>)   # <- For all F instances,<br>
                           # offset of 'name' in `F().__dict__`s<br>
                           # will be the same<br>
<br>
If LOAD_ATTR gets too many cache misses (20 in my current patch) it gets<br>
deoptimized, and the default implementation is used.  So if the code is<br>
very dynamic - there's no improvement, but no performance penalty either.<br>
<br>
In my patch, I use the cache to store (for LOAD_ATTR specifically):<br>
<br>
- pointer to object's type<br>
- type->tp_version_tag<br>
- the last successful __dict__ offset<br>
<br>
The first two fields are used to make sure that we have objects of the<br>
same type.  If it changes, we deoptimize the opcode immediately.  Then<br>
we try the offset.  If it's successful - we have a cache hit.  If not,<br>
that's fine, we'll try another few times before deoptimizing the opcode.<br></blockquote><div><br></div><div>So this is a third "next step" that has its own issue?</div><div><br></div><div>-Brett</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
><br>
>     What do you think?<br>
><br>
><br>
> It all looks great to me!<br>
<br>
Thanks!<br>
<br>
Yury<br>
<br>
</blockquote></div></div>