Performance of Python Frameworks compared to Rails

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

http://blog.curiasolutions.com/2009/10/ ... d-shinier/

Ich Poste diesen Link nicht ganz uneigennützig *hrrhrr*
Bottle: Micro Web Framework + Development Blog
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Genauso (un)wichtig, wie es zu wissen, wie schnell eine Programmiersprache `fib(30)` berechnen kann, ist es glaube ich zu wissen, wie schnell man "Hallo Welt" auf einer Webseite anzeigen kann. Das soll mich aber nicht aufhalten.

Ich benutze mal "ab -c 15 -n 1000 http://127.0.0.1/" zum Test.

Mit Pythons 2.6.3 eingebautem WSGI-Server komme ich auf 1379 R/s und 11 ms/R.

Mir ist aufgefallen, dass das Beispiel `return 'Hallo'` macht und nicht `return ['Hallo']`. Ersteres funktioniert, weil ein String wie eine Liste von Buchstaben aufgefasst wird. Die zweite Variante ist aber deutlich schneller: 2075 R/s und 7 ms/R.

Nutze ich Python 3.1, erreiche ich 1095 R/s und 14 ms/R.

Das einfache Django-Beispiel bekomme ich mit dem Entwicklungsserver nicht immer zum Laufen: 1562 R/s und 10 ms/R. Für das Template-Beispiel muss ich schon auf "-c 8" herunter gehen: 782 ms/R und 8 ms/R. Und für hellodb (mit "-c 8") erreiche ich 395 R/s und 18 ms/R. Ein fairer Test wäre jetzt mit mod_wsgi, aber das habe ich keine Lust zu installieren.

Stattdessen lieber Tornado: 3191 R/s und 5 ms/R. Soll es noch schneller sein? Dann gehe ich auf "-c 50" und erreiche 3394 R/s bei 15 ms/R.

Baue ich das Template-Beispiel von Django für Tornado nach (was einfach ist, weil die beiden Formate fast identisch sind) erreiche ich 2765 R/s mit 6 ms/R bei "-c 15" und 2757 R/s mit 18 ms/R bei "-c 50".

Bottle performt das Hallo-Welt bei mir mit 1876 R/s und 8 ms/R. Bei Templates (das Beispiel ist unfair, da die Vererbung fehlt) ist "-c 15" manchmal schon zu viel. Wenn's durchläuft, erreiche ich 1119 R/s bei 13 ms/R.

Kommen wir zu Ruby 1.8.7 und Rack:

Code: Alles auswählen

run Proc.new {|env| [200, {"Content-Type" => "text/html"}, "Hello Rack!"]}
"-c 15" ist für den eingebauten Mongrel-Server zu viel. Mit "-c 7" komme ich auf 244 R/s und 29 ms/R. Mit Rails 2.3.4 komme ich auf 183 R/s und 38 ms/R für "Hallo, Welt" und 183 R/s und 39 ms/R für die Templates - sprich, es ist egal.

Aber ich habe "Thin", das Äquivalent zu Tornado. Zurück auf "-c 15" schaffe ich 4151 R/s und 4 ms/R. Mit "-c 50" erreiche ich auf 4410 R/s und 11 ms/R.

Rails unter Thin schafft 681 R/s und 22 ms/R bzw. 652 R/s und 77 ms/R.

Zugegeben läuft Thin bei mir unter Ruby 1.9. Das ist im Schnitt doppelt so schnell wie Ruby 1.8.7.

Dennoch: Thin gewinnt denn Hello-World-Kontest.

Stefan
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Der django Entwicklungsserver zur Performance Messung macht keinen Sinn. Der ist nicht multithreaded...

"Hello World" Tests sind Praxis fern. Interessanter wäre es, wenn es eine kleine Web App wäre, die ein wenig Sinn macht ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Wer mag, kann ja mod_wsgi oder mod_fcgi für Django ergänzen und das ganze dann an meinen anderen Angaben kallibrieren. Unter Linux meine ich aber, dass Tornado noch schneller sein müsste als unter OS X, da dort doch extra diese epoll-Bibliothek benutzt wird. Für Thin könnte das Gleiche gelten.

Und ja, natürlich ist das Testen von "Hallo Welt" grenzwertig sinnlos.

Aber finde doch erst mal ein nicht-trivial aber nicht zu kompliziertes Beispiel, das nicht von der Datenbank oder allgemein IO begrenzt ist, sondern misst, wie schnell ein Request verarbeitet wird. Und dann finde Freiwillige, die das auf die verschiedenen Sprachen und Rahmenwerke portieren.

Wenn du da etwas hast, das mir gefällt, beteilige ich mich mit einer Technologie meiner Wahl :)

Stefan
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

sma hat geschrieben:Aber finde doch erst mal ein nicht-trivial aber nicht zu kompliziertes Beispiel, das nicht von der Datenbank oder allgemein IO begrenzt ist, sondern misst, wie schnell ein Request verarbeitet wird. Und dann finde Freiwillige, die das auf die verschiedenen Sprachen und Rahmenwerke portieren.
Die Frage ist, ob es überhaupt Sinn macht, die Dankenbank fast weg zu lassen.
Schließlich sollte es um das gesamte gehen. Was nützt es, wenn der Request blitz schnell ist, ORM/Template super langsam sind. Wenn man es noch Praxis relevanter machen würde, dann wäre Caching auch noch ein Thema. Dann wird es allerdings richtig kompliziert ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Sehe ich anders. Ich will weder DB noch Memcached oder was auch immer durchmessen, sondern den Teil, der in Python, Ruby, JavaScript, Smalltalk usw. geschrieben ist und mir hilft, zu einer URL eine HTML-Seite zu erzeugen -- oder meine Anwendung im Web zum Leben zu erwecken.

Stefan
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Will mal jemand meine Cython-kompatible Version geschwindigkeitsvergleichen? Die Tests laufen durch. Ich weiß aber nicht, ob ich nicht irgendwo Bugs reingemacht hab ;)
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

sma hat geschrieben:Sehe ich anders. Ich will weder DB noch Memcached oder was auch immer durchmessen, sondern den Teil, der in Python, Ruby, JavaScript, Smalltalk usw. geschrieben ist und mir hilft, zu einer URL eine HTML-Seite zu erzeugen -- oder meine Anwendung im Web zum Leben zu erwecken.
Richtig. Ein "Hello World" Vergleich macht durchaus Sinn, da er den Overhead des Frameworks auf zeigt. Die Zahlen dürfen natürlich nicht als absolute Zahlen betrachtet werden, sondern nur im Bezug zueinander.

Framework A braucht 1ms pro Request. Framework B braucht aber nur 0.1ms/Request. Das sind effektiv 0.9ms, die ich pro Request mehr Zeit für wichtigeren Code habe. Wenn die Frameworks sonst vergleichbar sind, macht es schon Sinn, darauf zu achten.

Einen 'Full Stack' zu testen ist nur dann sinnvoll, wenn man die Machbarkeit testen möchte (Schafft mein Server überhaupt X Requests/Sekunde?) oder wenn sich der Stack nicht auf teilen lässt. Sind die Einzelteile (DB/Templates/WSGI) aber trenn- und austauschbar, sollte man sie auch getrennt testen.
Bottle: Micro Web Framework + Development Blog
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Also das sehe ich ein wenig anders. Mit einem Hello World misst man nur den Overhead für diesen Teil. Gerade in django werden so einige Funktionen überhaupt nicht beachtet, wenn man diese in der settings.py abklemmt.

Somit ist ein "Hello World"-Overhead nicht zu vergleichen mit einem Overhead der mit einer Real World Beispiel entstehen würde.

Wie gesagt, man müßte IMHO eine keine Mini App erstellen, die ein wenig Praxis näher ist. Die Unterschiede die man dabei sieht, wäre interessant.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

Ein Framework sollte eigentlich keine Rechenzeit in Features verschwenden, die von der app nicht benutzt werden. Wenn ein Framework bei jedem Request sein komplettes ORM Modul initiiert (Beispiel), obwohl die app keine Datenbank verwendet, dann ist das schon eine Schwäche, die sich gerne in den Benchmark-Zahlen wieder spiegeln darf.

Dinge, die sich in der Praxis noch aus wirken, sind Templates und Datenbank-Anfragen. Dabei sollte man immer das vom Framework vorgeschlagene Modul verwenden oder ein externes Modul benutzt, wenn das Framework keines vor schlägt. Aber genau das hat der verlinkte Artikel doch getan? Und die Zahlenverhältnisse haben sich nicht besonders verändert. Wenn du nun statt einem SQL Query gleich 20 ein baust, dann wäre das zwar näher an einem echten Szenario, aber absolut wertlos für jede Form der Messung, da du damit die Datenbank und nicht das Framework testest.

Ein weiteres Problem bei einem Full-Stack Test ist, das du die Stärken und Schwächen der einzelnen Frameworks nicht heraus arbeiten kannst, wenn du alles auf einmal messen willst. Zum Beispiel fällt beim verlinkten Test auf, das Django Probleme mit Templates zu haben scheint und fast seinen zweiten Platz an Pylons verliert, Rails dagegen TG hinter sich lässt, sobald Datenbanken im Spiel sind.

Ich frage mal konkret: Was müsste denn noch getestet werden, um einen Praxisnahen Test zu erzeugen. Bedenke aber folgendes:
- DiskIO, Datenbank-Abfragen (nicht deren Verarbeitung), Netzwerk-Latenzen und alle nativen Python Funktionen (Schleifen, ...) sind bei allen Frameworks exakt gleich schnell. Wenn du also fair testen möchtest, sollten diese Faktoren nicht ins Gewicht fallen und den Test auch nicht verwässern.
- Was in der Praxis gebraucht wird, ist verschieden. Die eine API produziert nur kleine JSON schnipsel, die Andere baut aus 500 Datenbankabfragen ein riesiges Template zu zusammen. Wenn du fair sein sollst, musst du alle Möglichkeiten testen.

Macht es da nicht mehr sinn, die einzelnen Teile zu testen? Und "Hello World" testet eben den Core des Frameworks. Was ist daran jetzt so schlecht?
jens hat geschrieben:Wie gesagt, man müßte IMHO eine keine Mini App erstellen, die ein wenig Praxis näher ist. Die Unterschiede die man dabei sieht, wäre interessant.
Ich freu mich darauf, deine Ergebnisse zu lesen.
Bottle: Micro Web Framework + Development Blog
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

Das, was Graham Dumpleton (Autor von mod_wsgi) zu 'Hello World' Tests gesagt hat, finde ich auch recht einleuchtend:
Jens, a very basic hello world test may not say too much, but hello world tests can still be informative for developers of frameworks if they go to the extent of breaking down how much time is spent in each major component within their system. That is, routing, database, data processing and templating. And then varying the complexity of configured routing and templates to gauge how the growing complexity affects the throughput ability. To do this in a meaningful way you can’t just use any application as you need to control that complexity in a step wise fashion to get meaningful results.
Bottle: Micro Web Framework + Development Blog
Antworten