
Optimizing Python – A Case Study - dpmehta02
https://www.airpair.com/python/posts/optimizing-python-code
======
vosper
He's missing Cython, which is another good option when you're looking for
speed.

My personal favourite optimisation, from needing to shave a few milliseconds
off our API response times, was discovering that it's measurably slower to use
* args and * *kwargs, and switching to explicitly declaring and passing
arguments in the relevant parts of the code.

We also did a few other neat things:

\- Rolled our own UUID-like generator in pure Python (I was surprised this
helped, but the profiler doesn't lie)

\- Switched to working directly with WebOb Request and Response objects rather
than using a framework

\- Used a background thread with a single slot queue to make sure our response
was returned to the user before we emitted the event log message, but always
emit the message before moving to the next request

\- Heavy optimisation of memcache / redis reads and writes

Edit: Fixed formatting

~~~
jMyles
\- Used a background thread with a single slot queue to make sure our response
was returned to the user before we emitted the event log message, but always
emit the message before moving to the next request

The crosstown_traffic API in hendrix does exactly this.

[https://github.com/hangarunderground/hendrix](https://github.com/hangarunderground/hendrix)

~~~
vosper
Hey, that's kinda cool - thanks for the link!

~~~
jMyles
No doubt. I'm loving hendrix (and, thus, twisted). It has given me renewed
enthusiasm for python as a networking language.

Come check out #hendrix on freenode.

------
sitkack
The order of tactics to take is wrong. In terms of energy expended, one should
use PyPy first! It is amazingly compatible with CPython and can now be
embedded directly in CPython programs,
[https://github.com/fijal/jitpy](https://github.com/fijal/jitpy) (supports
numpy arrays)

Dump your virtualenv, create a new one with pypy, reinstall libraries and test
your app. Takes less than 20 minutes, even for complex applications.

~~~
ma2rten
Except if you are using python 3 or numpy or any other library written in C.

~~~
Veratyr
A lot (but definitely not all) of Numpy is actually Pypy compatible:
[http://buildbot.pypy.org/numpy-
status/latest.html](http://buildbot.pypy.org/numpy-status/latest.html)

------
clickok
Serious question: if you have some code that really has to be fast, is it
viable to keep it in Python, or should you ultimately end up rewriting it in a
compiled language?

For example, I am writing code that implements networks that evolve over time
for AI research. Prototyping it in Python makes it easy to test things out,
but I expect that I will have to rewrite it in C++ or maybe something more
fun, like Haskell[1].

1\. Mostly for the sheer joy of trolling my colleagues with a learning agent
monad.

~~~
p1esk
Same question to you: if you have some code that really has to be fast, is it
viable to keep it in C++, or should you ultimately end up rewriting it for
GPU?

~~~
wallstop
Is this really a suitable counter-question? GPUs lend themselvse towards
specific kinds of programming problems + added latency of GPU communication.
On the contrary, the cost between switching from any on-CPU language is
programmer time that may result in significant runtime advantages.

~~~
vetinari
Also disadvantages: increased programmer time for implementing new features.
Risks: you might optimize the wrong part (i.e. you invest into rewrite, but it
will not solve performance problems).

That's why you must quantify advantages and disadvantages, including risks
minimization and only then you'll see, whether given course of action is
viable.

------
pepijndevos
> Think for a second: time is only ever going to increase

Well, most of the time at least. Think about DST and leap seconds.

~~~
ryan_sb
True, but in this particular case, the cost to time going (temporarily)
backwards would only be connecting to a potentially-suboptimal disque node,
and that would be remedied after the subjective-machine-time caught up with
the previous subjective time.

------
mangeletti
Isn't Jython _not_ a JIT compiler, and isn't Jython much slower than cPython?

~~~
coldtea
Nope and Nope. Jython is made to run on the HotSpot which is a JIT compiler,
and Jython should be comparable to speed to cPython and faster in some cases
(used to be slower, but that was 3-4 years ago, the optimized it a lot, and
added stuff in Java 7/8 helped too).

JRuby is faster than standard C Ruby too.

~~~
DasIch
There is a huge difference between an interpreter with a JIT compiler and an
interpreter running on another interpreter that has one. These are not
equivalent at all.

~~~
coldtea
Jython is not running on an interpreter.

It IS an interpret itself, and it runs on a virtual machine that takes care of
JIT compilation.

~~~
paulfurtado
In the JRuby case, JRuby compiles Ruby to JVM bytecode.

Jython may do the same: rather than create cpython bytecode it may produce JVM
bytecode which may be optimized by the JVM. However, I do not know anything
about Jython performance and they could not be employing the same tactics as
JRuby.

With modern Java features like lambdas coming into java 7 and 8 and other
interesting languages like Scala, Groovy, etc being written for the JVM I'm
sure things have come a long way since the time jython 2.4 was being developed
on Java 5/6 and I'm sure the JVM has many more optimizations that dynamic
languages may benefit from.

~~~
vorg
> other interesting languages like Scala, Groovy, etc being written for the
> JVM

I think Clojure is one of the most interesting so I'm keen you include it in
your minimal list of examples. I don't think Clojure actually uses the Java 7
"invoke dynamic" bytecode though.

------
aburan28
Pythran is also missing

~~~
accounthere
As is Nuitka, but who keeps track of these things?

