Wie ich in vorigen Posten schrieb, suchte ich vor einigen Monaten ein Framework für die Arbeit aus. Die wichtigsten Parameter dabei waren für mich sowie Einfachheit seiner Benutzung als auch seine Stabilität und Schnellwirkung.
Wegen fehlender konkreter umfassender Information im Internet über Leistungsfähigkeitsvergleich der Frameworks (ich habe nur einen einzigen ziemlich nackten Test gefunden: Er hat sich auf drei Frameworks RubyOnRails, Django, Symfony beschränkt und keine Detail enthalten), habe ich die detaillierte Analyse für den Beschluß des optimalsten in Schnellwirkung und Stabilität des 6 führenden Frameworks durchgeführt.

Update 04.Feb.2007: Pylons, RoR 1.2.1, CakePHP + eAccelerator, Zend, Turbogears with Cheetah, Jinja, Genshi

Das Ziel des Tests war also der Beschluß der Leistung des Frameworks selbst, sowie deren Vergleich untereinander in Geschwindigkeit beim Seitengenerieren und in maximaler Zahl der Anfragen bei gegebener Konfiguration.
Ich habe ein Testmodell ausgewählt, in der Kontroller eine bestimmte Schablone gerendert und eine Antwort generiert hat. Im Ergebnis hätte sich ein HTM-File „Hello World!“ ergeben. (unten ist die Coden für jeden Framework zu finden). Die Database wurde im Test ausgelassen, weil sie selbst bedeutend die Arbeitsgeschwindigkeit beschränkt.

Ich habe nicht vorgehabt, die Funktionalität der Frameworks, Community, Arbeit mit Database zu vergleichen. Wie gesagt, für mich war es wichtig die Geschwindigkeit selbst des MVC- Frameworks, bei möglichst kleineren Einfluß der äußeren Faktoren zu bestimmen. Deswegen habe ich Nginx + FCGI durch IP:PORT benutzt.

Es wurden folgende Frameworks getestet:
Der Test wurde an folgenden Hardware und mit der Software durchgeführt:
CPU: AMD OpteronT Processor 146 (2 GHz)
Memory: 2 GB
OS: Debian 3.1 (Linux 2.6.14)
Web-Server: nginx/0.5.5
Versionen der Frameworks und der Programmierungssprachen:
  • CodeIgniter 1.5.1
  • Catalyst 5.7006 Rev.5996
  • Django Rev.4254 (28Dec.2006)
  • RoR 1.1.6
  • RoR 1.2.1
  • Symfony 1.0beta2 SVN-Rev 3122
  • Turbogears 1.0b3 Rev.2323
  • Python 2.4.4
  • Python Psyco 1.5.2
  • Flup Rev.2303
  • Ruby 1.8.5-p12
  • mongrel 0.3.13.4
  • PHP 5.2.0 (cgi-fcgi)
  • perl, v5.8.4
  • CPAN ver 1.8802
Programme für den Test:
Siege 2.65 http://www.joedog.org/JoeDog/Siege
Http_load 12.03.2006 http://www.acme.com/software/http_load/
ab 2.0.41-dev Rev: 1.141
Methodologie des Tests:
  • Speichermessung (ps aux: VSZ "virtual set size" и RSS "resident set size").
  • Test ApacheBenchmark (2 Mal nacheinander)
  • ab -c 5 -n 1000 http://project.com/
  • Speichermessung und Messung der verbrauchten Zeit des Prozessors (ps aux: VSZ, RSS, %CPU, %MEM)
  • Neustarten des Frameworks
  • Test ApacheBenchmark (2 Mal nacheinander)
  • ab -c 100 -n 10000 http://project.com/
  • Speichermessung und Messung der verbrauchten Zeit des Prozessors
  • Neustarten des Frameworks
  • Messung http_load
  • http_load -rate 10 -seconds 5 project.com
  • Speichermessung und Messung der verbrauchten Zeit des Prozessors
  • Neustarten des Frameworks
  • Test Siege mit 50 gleichzeitigen Benutzer im Laufe einer Minute
  • siege -d1 -t1M -c50 project.com
  • Test Siege mit 200 gleichzeitigen Benutzer im Laufe einer Minute
  • siege -d1 -t1M -c200 project.com
  • Test Siege mit 300 gleichzeitigen Benutzer im Laufe einer Minute
  • siege -d1 -t1M -c300 project.com
  • Speichermessung und Messung der verbrauchten Zeit des Prozessors
Kommentare zur Methodologie:

Für Anfang habe ich nur Nginx mit einfachster Konfiguration benutzt, bei dem auf jede Anfrage ein transparentes Gif-file 43Bytes-Größe rauskommt, der mit dem Server generiert wird.
Dank dem Test wurde die annähernd maximale Aufnahmefähigkeit des Servers selbst bestimmt. Ich sage im Voraus, dass sie zehnmal größer als Leistung des schnellsten Frameworks ist.
Alle Frameworks wurden als FastCGI 127.0.0.1:PORT gestartet. Wenn ein Framework „development“ und „production“ Modus vorsieht, ich habe mit „production“ gearbeitet.
Im Nginx habe ich gleiche Konfiguration für alle Frameworks benutzt.
Jedes Framework habe ich neu gestartet, um die Statistik zwischen den Tests verschiedener Programmen zu entleeren.

Meine subjektiven Ergänzungen für jedes Framework bei Installation und Start:
  1. CodeIgniter
    simple bei Einstellungen. Keine Probleme zu sehen. Für den Start habe ich spawn-php.sh mit fünf Prozessen benutzt.
    Ziemlich flink für PHP.
  2. Catalyst
    Für den Anfang muss man CPAN und ein Paar Module für FCGI einstellen. Selbst die Einstellung sah irgendwie verworren.
    Start ist ebenso kompliziert. Am Anfang muss Framework
    ./CatInABox/start.sh
    gestartet werden.
    Erst dann selbst das Projekt
    ./script/world_fastcgi.pl -l 127.0.0.1:9500 -n 5
    Der Code ist nicht einfach, man kann aber zur Recht kommen.
  3. Django
    Leicht einzustellen vom Repositarium. Die Projekte entstehen auch einfach. Mit zwei Methoden prefork und threaded gestartet. Obwohl funktioniert Phyton mit threads nicht so perfekt.
    python manage.py runfcgi method=threaded host=127.0.0.1 port=8801
    python manage.py runfcgi method=prefork host=127.0.0.1 port=8801
    Framework auch mit dem Modul psyco geprüft. In manage.py eingesetzt:
    from django.core.management import execute_manager
    import psyco
    psyco.full()
  4. RubyOnRails
    Leicht einzustellen nach der Instruktion von der Seite, aber kompliziert zu starten. Obwohl ich im Internet verschiedene Konfigurationen für Nginx+FastCGI gesehen, hat es nicht geklappt es zusammen mit dem Nginx zu starten.
    Start mit lighttpd+FastCGI war aber doch unproblematisch. Deswegen habe ich „offizele“ Rekomendation benutzt es durch den Server „mongrel“ zu starten.
    Dank dem Aleksej Kovyrin kann man den Multiplikationskoeffizient überschlagen.
    Nginx +FCGI ist schneller ungefähr in 1.29 Mal als Nginx + Mongrel.
    Gestartet 5 Servers Mongrel:
    mongrel_rails start -d -e production --port 8501 --pid /tmp/rb1.pid
    mongrel_rails start -d -e production --port 8502 --pid /tmp/rb2.pid
    mongrel_rails start -d -e production --port 8503 --pid /tmp/rb3.pid
    mongrel_rails start -d -e production --port 8504 --pid /tmp/rb4.pid
    mongrel_rails start -d -e production --port 8505 --pid /tmp/rb5.pid
    
    In ein paar Tagen nach Testführung ist die neue Version RoR 1.2.1 zur Welt gekommen.
    Klar habe ich sie auch getestet mit allen gleichen Parametern. Die Ergebnisse sind etwas schockierend – zweimal-Leistungsfähigkeit-Sinkung in allen Tests im Vergleich zur vorigen Version!
  5. Symfony
    Lässt sich unkompliziert einstellen, ist aber total komisch in der Arbeit mit Projekten selbst. Ziemlich verwickelt.
    Für den Start habe ich auch spawn-php.sh mit fünf Prozessen benutzt.
  6. TurboGears
    Beim Einstellen entstanden ein paar Probleme, die ich jedoch nach einiger Zeit gelöst habe.
    Für den Start in threaded-Modus habe ich ein Skript benutzt, in dem
    from fcgi import WSGIServer
    	auf
    from flup.server.fcgi  import WSGIServer
    
    WSGIServer(application=wsgiApp).run()                                                                                                                                                               
    	auf
    WSGIServer(application=wsgiApp, bindAddress=
    ('127.0.0.1', 8900)).run()
    geändert habe.

Konfigurationsfiles des web-Servers: Code der Projekten jedes Frameworks: Skript des Startes PHP-FCGI: Ergebnisse des web-Servers fürs Vergleich: Ergebnisse für jedes Framework im einzelnen: Ergebnisse:
  1. Test ApacheBenchmark
    • Tabelle der Bearbeitaungsgeschwindigkeit der Anfragen
      Tabelle der Bearbeitaungsgeschwindigkeit der Anfragen

      * 1) zweites mal Framework ist down
      * 2) der Multiplikationskoeffizient nach Kovyrin = 1.29. Fürs Ändern "mongrel" in "fastcgi".
    • Schaubild der Bearbeitaungsgeschwindigkeit der Anfragen. Test „ab c 5 n 1000“.
      Schaubild der Bearbeitaungsgeschwindigkeit der Anfragen. Test ab c5 n1000
    • Schaubild der Bearbeitaungsgeschwindigkeit der Anfragen. Test „ab c 100 n 10000“.
      Schaubild der Bearbeitaungsgeschwindigkeit der Anfragen. Test ab c 100 n 10000
    • Speicherverbrauch vor und nach dem Test
      Speicherverbrauch vor und nach dem Test
      * 3) Python ist so geschaffen, dass er die Prozesse im prefork-Modus bei großer Auslastung neustartet. Deswegen ist es unmöglich, die reale CPU-Auslastung und maximalen Speicherverbrauch zu bestimmen.
    • VSZ "virtual set size"
      VSZ
    • RSS "resident set size"
      RSS
    • Auslastung des Prozessors
      Auslastung des Prozessors
  2. Test http_load
    • Tabelle mit Ergebnissen
      Tabelle mit Ergebnissen
    • Schaubild mit der Verbindungszeit
      Schaubild mit der Verbindungszeit
    • Schaubild mit der Antwortzeit erster Verbindung
      Schaubild  mit der Antwortzeit erster Verbindung
  3. Siege Test
    • Allgemeine Tabelle mit Ergebnissen
      Allgemeine Tabelle mit Ergebnissen
    • Transaktionsschaubild
      Transaktionsschaubild
    • Antwortzeit
      Antwortzeit
    • Die längste Transaktionszeit
      Die längste Transaktionszeit
    • Speicherverbrauch nach dem Test
      Speicherverbrauch nach dem Test
    • Auslastung des Prozessors
      Auslastung des Prozessors

Zusammenfassungen:

Die Resultate sind nach den Tabellen und Schaubildern zu betrachten.
Einige kurze Ergänzungen:
Dajngo hat den kleinsten Prozessorverbrauch.
Catalyst hat gewundert, bei übermäßiger Auslastung lastet er den Prozessor. Obwohl Verluste der Anfragen waren dabei nicht zu sehen.
RoR 1.2.1 lastet ebenso den Prozessor bei der hohen Auslastung.
Interessant ist TurboGears, der die kleine Verbrauchszeit CPU im Test „ab“ zeigte, aber das schlechteste Resultat im Siege-Test hatte.
Catalyst hat den größten Speicherverbrauch, bei RoR ist es wahrscheinlich mit dem Start durch mongrel zu erklären.
PHP-Frameworks nehmen viele CPU-Reserven sogar im ruhigen Zustand ein.

Durchschnittlische Connectszeit ist ungefähr für alle gleich. Die „first-response“ Zeit ist sehr unterschiedlich. Django hat kleinste durchschnittliche Zeit, maximale Zeit ist die größte. Python-Frameworks haben sich gut gezeigt, RoR hat enttäuscht.

Im Siege-Test bei den CodeIgniter, Symphony, RoR 1.2.1 & 1.1.6 waren Verlusste bei großer Anzahl der „concurrent users“ zu beobachten.
Ruby ist schnell bei kleiner Auslastung, bei der großen users-Anzahl aber verliert stark die Produktivität.

Psyco beschleunigt Django auf 15-30%, dafür hat man aber mit gestiegenem Speicherverbrauch VSZ auf 80% in prefork- und auf 400% (!!) in treaded-Modus zu zahlen. RSS-Verbrauch wächst in 2-2.5 mal.
Prefork Modus nimmt mehr Speicher, dafür bekommt man aber ein stabil funktionierendes bei großen Auslastungen System und kleineren Reservenverbrauch des Prozessors.
In treaded Modus hängte Django unter großer Auslastung und antwortete auf keine Anfragen.
Dasselbe geschah auch mit dem TurboGears. Es liegt an schlechter Funktionalität in treaded Modus des Pythons.

Kommentare vom Ivan Sagalaev:

„- FCGI Server ist in threaded Modus gestartet. Bekannt, dass Phyton arbeitet in treads wesentlich langsamer wegen GIL (Global Interpreter Lock), in dem alle treads oft einfach aufeinander warten müssen: der Interpreter kann ja nur von einem davon benutzt werden. Deswegen in unix lohnt es sich nach Möglichkeit die Server mit Phyton-Code in prefork-Modus zu starten – es wird schneller sein. Übrigens, bei Windows ist die Situation umgekehrt, weil die Prozessschaffung da viel langsamer ist als in unix, außerdem so gut ich weiß, Phyton spinnt da doch weniger. - was Psyco angeht. Django-Developers haben es getestet und etwas interessantes rausgefunden. An 32Bit –Systems gibt es wirklich Zuwachs an Leistungsfähigkeit. Und an 64Bit umgekehrt sinkt sie. Es gescheht deswegen, dass mit Psyco schaltet der Prozessor in 32Bit-Regime um und benutzt keine Vorzüge seiner Architektur. Wenn das alles stimmt, dann bedeutet wahrscheinlich der Fakt, dass mit Psyco Django schneller arbeitet, dass Linux und Phyton nicht in 64Bit-System sind (trotz der Arbeit an Opteron). Stimmt es?“

Ja, System ist 32Bit.

Platzverteilung nach dem Test:
  1. mehr als dreifach im Vergleich mit den nähersten Konkurenten hat Django gewonnen.
  2. TurboGears und RoR 1.1.6. Sie sind gleich schnell, benehmen sich zwar unterschiedlich bei verschiedenen Auslastungen, einander überholend.
  3. .
  4. Catalyst. Ehrlich gesagt habe ich vom Perl mehr erwartet.
  5. CodeIgniter. PHP-Frameworks wie auch gedacht, sind die langsamsten. CodeIgniter sind für diejenige zu empfehlen, die nur an PHP programmieren, gleichzeitig auch das geeignetes System haben wollen.
  6. Resultaten des RoRs 1.2.1 sich wie schon erwähnt schockierend: Sinkung der Leistungsfähigkeit in 2-4 mal im Vergleich zur 1.1.6 Version. Doppelt große „first-response“ in http_load und übermäßig großer Zeitverbrauch des Prozessors zeugen höchstwahrscheinlich von einem Fehler in neuer Version.
  7. Symphonie hat letzten Platz. Sehr komplizierstes und langsames Framework. Unterschied mit Django ist über 35 mal (!!).

P.S. Wegen dem Zusatz zu Django des Beschleunigermoduls Psyco im Test habe ich auf einigen Bitten hin einen kurzen Test für PHP mit dem eAccelerator-0.9.5 gemacht.
Ich habe 2 mal nacheinander folgende Befehle benutzt:
ab -c 5 -n 1000 http://ci.test.com/
ab -c 100 -n 10000 http://ci.test.com/
Als Ergebnis funktioniert CodeIgniter 6,5 mal schneller, gibt bis 600 Anfragen/Sek aus.
Die Differenz mit Django hat bis 2 Mal gekürtzt.
Hier sind die Ergebnisse

153 Votes | Average: 4.5 out of 5153 Votes | Average: 4.5 out of 5153 Votes | Average: 4.5 out of 5153 Votes | Average: 4.5 out of 5153 Votes | Average: 4.5 out of 5 (153 votes, average: 4.5 out of 5)
Loading ... Loading ...

Top Posts: