Python 3 Performance: A Red Herring?
This entry was split from an overly long journal entry entitled Why Python 3?
I was once guilty of dwelling on raw language performance, but no longer. For the work I do, developer productivity is much more important than raw language speed. It doesn't trouble me at all that Python 3 is a little slower than the most recent 2.x release we have in production (2.5). History has shown the Python developer group are rather good at optimizing Python under the hood, so now that the language implementation has stabilized, we can look forward to plenty of optimizations coming to the 3 branch in time.
Yet Python 3 today is no slouch. For the work I do -- web application development -- I'm finding the first release of Python 3 performs roughly equivalent to Python 2.5.x, and that matters more to me than pystone or some other abstract measure.
Benchmark 1: pystone
Speaking of pystone, here is how this old single processor Unix workstation I'm using stacks up:
$ python2.5 /usr/local/lib/python2.5/test/pystone.py Pystone(1.1) time for 50000 passes = 1.75781 This machine benchmarks at 28444.4 pystones/second $ python2.6 /usr/local/lib/python2.6/test/pystone.py Pystone(1.1) time for 50000 passes = 1.46094 This machine benchmarks at 34224.6 pystones/second $ python3.0 /usr/local/lib/python3.0/test/pystone.py Pystone(1.1) time for 50000 passes = 1.85938 This machine benchmarks at 26890.8 pystones/second
Benchmark 2: web app
Here is an obligatory (yet crude) web application benchmark - retrieving a wiki page - on the same old machine while gvim and a bunch of other stuff is also running:
ab -n 1000 http://127.0.0.1:8002/qwiki/foo/
Req/second
Python 2.5 174.79
Python 2.6 204.29
Python 3.0 173.49
Benchmark 3: web framework template
The following benchmark was based off a templating benchmark included in the Genshi package and utilizes Python's timeit module, averaging 10 passes creating a large html table using the following Qpy template:
# this is to provide a Qpy template for use in comparison
# with the Genshi "bigtable" benchmark.
table = [dict(a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,i=9,j=10)
for x in range(1000)]
def qpy_template:xml():
'<table>'
for row in table:
'<tr>'
for col in row.values():
'<td>%s</td>' % col
'</tr>'
'</table>'
You can see that Qpy isn't the only package to benefit from the improved performance in Python 2.6 and Python 3.0, and I'm sure we'll see need for speed type coptimization efforts in due course to bring some modules back to where they were:
$ python2.5 bigtable.py ElementTree 736.43 ms cStringIO 36.46 ms StringIO 141.10 ms list concat 22.73 ms Qpy Template 129.35 ms $ python2.6 bigtable.py ElementTree 656.99 ms cStringIO 30.85 ms StringIO 131.95 ms list concat 16.37 ms Qpy Template 39.54 ms $ python3.0 bigtable.py ElementTree 449.60 ms StringIO 138.03 ms list concat 21.70 ms Qpy Template 36.36 ms
Conclusion: There are valid reasons why one might choose Python 2.x today over Python 3.0, but raw performance is not likely to be one of them for many developers.