4 ms·
There's also wheezy.web[1], which was very fast compared to ordinary Python web frameworks. When I tested it locally a year ago, the results were the following:
by barosl 11y ago
There's also wheezy.web[1], which was very fast compared to ordinary Python web frameworks. When I tested it locally a year ago, the results were the following:
== Time spent to handle one request ==
CPU: Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz
WSGI : 1 microseconds
Wheezy : 10 microseconds
Bottle : 38 microseconds
Werkzeug : 47 microseconds
Morepath : 115 microseconds
Flask : 193 microseconds
Flask with Jinja: 267 microseconds
Cherrypy : 561 microseconds
Django : 816 microseconds
However, at the same time, this also made me more skeptical about the Python performance story. IIRC, wheezy.web was fast because it minimized the number of the function calls (only ~20 function calls per request were needed). This is reasonable, considering that function calls in Python are very costly, and there is no function inlining in CPython. (I'm not sure of PyPy, probably it has this kind of optimization?)
But less functions mean less modularity. I have to give up some modularity if I want to squeeze the last bit of performance from my Python code. I can't have both. This doesn't sound great because there has been a verified method to deal with this kind of problem - function inlining - for decades. And I cannot use it for Python.
[1] https://pypi.python.org/pypi/wheezy.web https://pypi.python.org/pypi/wheezy.web
- ptx 11y ago> there is no function inlining in CPython. Couldn't this be done with a decorator that on the first call to the decorated function looks up the variable bindings, extracts the bytecode of called functions and then merges it into its own (and renames variables etc.)? I'll leave the implementation as an exercise for the reader. :)
- barosl 11y agoThis is certainly an interesting idea. A quick Google search gave me this toy example: [1][2] Of course making it work for all cases would be very hard due to the excessive dynamism of Python, but for simple arithmetic operations it could be made to work fairly well. [1] http://tomforb.es/automatically-inline-python-function-calls http://tomforb.es/automatically-inline-python-function-calls [2] https://github.com/orf/inliner https://github.com/orf/inliner
- e12e 11y agoFrom some searching, this apparently is easier said than done[1] (read: there doesn't appear to be a way to guarantee that the decorator wouldn't break due to various meta-programming etc). Relevant links: The RPython sub-set used to implement pypy (and other languages on the rpython run-time) has a decorator for @always_inline, and does automagic inlining: https://mail.python.org/pipermail/pypy-commit/2014-November/086702.html https://mail.python.org/pipermail/pypy-commit/2014-November/... http://rpython.readthedocs.org/en/latest/translation.html#function-inlining http://rpython.readthedocs.org/en/latest/translation.html#fu... I'm not entirely clear on what is being governed by the pypy interpreter inline_trehshold -- if it's for both python code, or just for the interpreter: http://pypy.readthedocs.org/en/latest/config/translation.backendopt.inline_threshold.html http://pypy.readthedocs.org/en/latest/config/translation.bac... http://boxbase.org/entries/2015/apr/20/rpython-jit-optimizations/ http://boxbase.org/entries/2015/apr/20/rpython-jit-optimizat... There's a project to do AST level optimizations at (bytecode) compile time: https://pypi.python.org/pypi/astoptimizer https://pypi.python.org/pypi/astoptimizer There's been talk of using a decorator to allow for function inlining: [1] http://bugs.python.org/issue10399 http://bugs.python.org/issue10399
- merb 11y ago816 microseconds seems a bit off for Django, even under worst conditions I got way way better results on VPC's...
- todd8 11y agoI just wanted to point out that short code paths don't necessarily translate to poor code. Measuring the quality of code is tricky and certainly modularity is a positive, but just having a short fast code path doesn't mean the code isn't modular. I took a brief glance at the wheezy repo. The functions and methods looked pretty modular to me. $ sloccount $(find src -type d| grep -v tests) ... SLOC Directory SLOC-by-Language (Sorted) 994 handlers python=994 451 src python=451 316 middleware python=316 Totals grouped by language (dominant language first): python: 1761 (100.00%) Only 1761 non-test LOC, hmm... let's find out how large the functions really are: $ cat $( find scr -name '*.py' | grep -v tests ) | grep 'def ' | wc -l 87 $ cat $( find scr -name '*.py' | grep -v tests ) | grep 'class ' | wc -l 19 There appear to be 87 functions and methods in a total of 19 classes. This means the average function size is only 20 lines of code.