<html xmlns="http://www.w3.org/1999/xhtml">
<div name="messageBodySection" style="font-size: 14px; font-family: -apple-system, BlinkMacSystemFont, sans-serif;">There are several reasons for the issues you are mentioning.
<div><br /></div>
<div>1. Attribute look up is much more complicated than you would think.</div>
<div> (If you have the time, watch <a href="https://www.youtube.com/watch?v=kZtC_4Ecq1Y">https://www.youtube.com/watch?v=kZtC_4Ecq1Y</a> that will explain things better than I can)<br /></div>
<div> The series of operations that happen with every `obj.attr` occurrence can be complicated. It goes something like:<br /></div>
<div> def get_attr(obj, attr):</div>
<div>     if attr in obj.__dict__:</div>
<div>         value = obj.__dict__[attr]</div>
<div>         if is_descriptor(value):</div>
<div>             return value(obj)</div>
<div>         else:</div>
<div>             return value</div>
<div>     else:</div>
<div>         for cls in type(obj).mro():</div>
<div>             if attr in cls.__dict__:</div>
<div>                 value = cls.__dict__[attr]</div>
<div>                 if is_descriptor(value):</div>
<div>                     return value(obj)</div>
<div>                 else:</div>
<div>                     return value</div>
<div>         else:</div>
<div>             raise AttributeError('Attribute %s not found' % attr)</div>
<div> <br /></div>
<div> Therefore, the caching means this operation is only done once instead of n times (where n = len(whatevers))<br /></div>
<div>2. Function calls</div>
<div name="messageReplySection" style="font-size: 14px; font-family: -apple-system, BlinkMacSystemFont, sans-serif;"><br />
<div>3. Dynamic code makes things harder to optimize</div>
<div> Python’s object model allows for constructs that are very hard to optimize without knowing about the structure of the data ahead of time.</div>
<div> For instance, if an attribute is defined by a property, there are no guarantees of obj.attr will return the same thing.<br /></div>
<div> <br /></div>
<div> So in simple terms, the power Python gives you over the language makes it harder to optimize the language.<br /></div>
<div><br /></div>
<div>4. CPython’s compiler makes (as a rule) no optimizations</div>
<div> CPython’s compiler is a fairly direct source-to-bytecode compiler, not an actual optimizing compiler. So anything beyond constant-folding and<br /></div>
<div> deletion of some types of debug code, the language isn’t going to worry about optimizing things for you.<br /></div>
<div><br /></div>
<div>So in simple terms, of the languages you mentioned, JavaScript’s object model is substantially less powerful than Python’s, but it also is more straightforward</div>
<div>in terms of what obj.attr means, and the other 3 you mentioned all have statically-typed, optimizing compilers, with a straight-forward method resolution order.</div>
<div><br /></div>
<div>The things you see as flaws end up being the way Pythonistas can add more dynamic systems into their APIs (and since we don’t have macros, </div>
<div>most of our dynamic operations must be done at run-time).</div>
<div><br /></div>
<div>- Ed</div>
<div><br /></div>
On Jan 26, 2018, 16:36 -0500, Pau Freixes <pfreixes@gmail.com>, wrote:<br />
<blockquote type="cite" style="margin: 5px 5px; padding-left: 10px; border-left: thin solid #1abc9c;">Hi,<br />
<br />
This mail is the consequence of a true story, a story where CPython<br />
got defeated by Javascript, Java, C# and Go.<br />
<br />
One of the teams of the company where Im working had a kind of<br />
benchmark to compare the different languages on top of their<br />
respective "official" web servers such as Node.js, Aiohttp, Dropwizard<br />
and so on. The test by itself was pretty simple and tried to test the<br />
happy path of the logic, a piece of code that fetches N rules from<br />
another system and then apply them to X whatevers also fetched from<br />
another system, something like that<br />
<br />
def filter(rule, whatever):<br />
if rule.x in whatever.x:<br />
return True<br />
<br />
rules = get_rules()<br />
whatevers = get_whatevers()<br />
for rule in rules:<br />
for whatever in whatevers:<br />
if filter(rule, whatever):<br />
cnt = cnt + 1<br />
<br />
return cnt<br />
<br />
<br />
The performance of Python compared with the other languages was almost<br />
x10 times slower. It's true that they didn't optimize the code, but<br />
they did not for any language having for all of them the same cost in<br />
terms of iterations.<br />
<br />
Once I saw the code I proposed a pair of changes, remove the call to<br />
the filter function making it "inline" and caching the rule's<br />
attributes, something like that<br />
<br />
for rule in rules:<br />
x = rule.x<br />
for whatever in whatevers:<br />
if x in whatever.x:<br />
cnt += 1<br />
<br />
The performance of the CPython boosted x3/x4 just doing these "silly" things.<br />
<br />
The case of the rule cache IMHO is very striking, we have plenty<br />
examples in many repositories where the caching of none local<br />
variables is a widely used pattern, why hasn't been considered a way<br />
to do it implicitly and by default?<br />
<br />
The case of the slowness to call functions in CPython is quite<br />
recurrent and looks like its an unsolved problem at all.<br />
<br />
Sure I'm missing many things, and I do not have all of the<br />
information. This mail wants to get all of this information that might<br />
help me to understand why we are here - CPython - regarding this two<br />
slow patterns.<br />
<br />
This could be considered an unimportant thing, but its more relevant<br />
than someone could expect, at least IMHO. If the default code that you<br />
can write in a language is by default slow and exists an alternative<br />
to make it faster, this language is doing something wrong.<br />
<br />
BTW: pypy looks like is immunized [1]<br />
<br />
[1] https://gist.github.com/pfreixes/d60d00761093c3bdaf29da025a004582<br />
--<br />
--pau<br />
_______________________________________________<br />
Python-ideas mailing list<br />
Python-ideas@python.org<br />
https://mail.python.org/mailman/listinfo/python-ideas<br />
Code of Conduct: http://python.org/psf/codeofconduct/<br /></blockquote>