Python and the need for speed

Steven D'Aprano steve at pearwood.info
Sun Apr 9 03:39:06 EDT 2017


On Sun, 09 Apr 2017 13:57:28 +1000, Chris Angelico wrote:

> On Sun, Apr 9, 2017 at 10:20 AM,  <breamoreboy at gmail.com> wrote:
>> I've an idea that http://www.mos6581.org/python_need_for_speed is a
>> week late for April Fool's but just in case I'm sure that some of you
>> may wish to comment.

I'm not sure why Mark thinks that wanting Python to be faster is a joke. 
As the page points out, there are many projects attempting (with greater 
or lesser success) to speed up Python.

I'm happy for Mark if his need for high performance is low, but CPython 
at least is definitely in the middle-tier of performance, and PyPy isn't 
suitable for all use-cases. I don't know anyone who has ever said "this 
interpreter is too fast, can you make it run slower?"


>>From that page:
> 
>> Other candidates for banishment from TurboPython include eval and exec.
> 
> Bye bye namedtuple. 

All that would mean is that the implementation of namedtuple would have 
to change. It would probably require some sort of support from the 
compiler, but that's okay, the compiler can do (nearly) anything.

Something as important and useful as namedtuple would not be dropped from 
this hypothetical TurboPython. It would just shift the implementation 
from pure-Python to something else.

exec() is actually only needed for a *tiny* bit of namedtuple. The 
original implementation by Raymond Hettinger takes the easy way out by 
using exec on the entire class definition, but it is trivially easy to 
restrict that to just the class __new__ method:

https://code.activestate.com/recipes/578918-yet-another-namedtuple


but even that could be avoided with a minimal amount of help from the 
compiler.


> And compile() is going to have to go, 

Indeed.


> since you
> could implement eval/exec by creating a new function:
> 
>>>> runme = r"""
>   print("Hello, world!")
>   import sys sys.stdout.write("I can import modules.\n")
> """
>>>> type(lambda: 1)(compile("def f():" + runme, "exec",
>>>> "exec").co_consts[0], globals())()
> Hello, world!
> I can import modules.
> 
> So if compile() goes, you also lose ast.parse, 

Probably.


> which means you lose introspection tools, 

*Some* introspection tools. Python has many that don't rely on compile or 
ast.parse.

Hell, even Java has some introspection tools, based on reflection, which 
lets you do Python-like things at runtime. Of course if you do this, you 
lose performance.


> plus you lose literal_eval and friends. 

I don't know what "friends" you are referring to, but again, if 
literal_eval is important, the compiler can support it. If you can 
support an entire Python interpreter and compiler in the form of 
compile(), then you can support more restricted subset of the language. 
Writing a parser to evaluate strings, integers, and a few other data 
types is not exactly brain surgery.



> I'm also
> not sure whether the import machinery would have to be rewritten, but a
> quick 'git grep' suggests that it would. Removing eval and exec is not
> as simple as removing them from the standard library.

Well of course not, but removing eval and exec is only a necessary, not 
sufficient, condition, for enabling a huge bunch of compiler optimizations 
and speeding up Python.

This "TurboPython" would require a completely new implementation of the 
Python interpreter to be fast. It's not as if eval and exec are great 
heavy concrete weights chained to the leg of the compiler, and all you 
need do is remove the chain and the compiler suddenly becomes thirty 
times faster.


> In fact, extreme dynamism is baked deep into the language. You'd have to
> make some fairly sweeping language changes to get any real benefits from
> restricting things. 

Well, maybe. As is pointed out many, many times, 99% of Python code 
avoids the sorts of extreme dynamism that keeps things slow. Lots of 
people would be satisfied with a language *really close* to Python that 
was ten or twenty times faster, even if it meant that you couldn't write 
code like this:


answer = input("What's your name?")
exec("name = %r" % answer)
print(name)


Even better would be if the compiler was smart enough to use the 
optimized, fast runtime when the dynamic features aren't used, and fall 
back on a slower implementation only when needed to support the more 
dynamic features.

I wonder how Victor Stinner's FAT Python is going?

http://faster-cpython.readthedocs.io/fat_python.html




> There are better ways to improve performance,

And yet Python lags behind Javascript and PHP for speed...



-- 
Steve


More information about the Python-list mailing list