Mai 31
JavaScript (NodeJS) vs. PHP vs. Python
Ich habe schonmal einen ähnlichen Artikel geschrieben, der allerdings mittlerweile veraltet ist und die meisten Seitenaufrufe meines Blogs produziert. http://ugamela-blog.pheelgood.net/2009/01/25/vergleich-php-vs-python-browsergame
Im letzten Artikel habe ich bereits über erste Erfahrungen mit NodeJS gesprochen: http://ugamela-blog.pheelgood.net/2011/04/29/nodejs/
Hier soll nun, ähnlich wie letztes Mal, ein Vergleich von Programmiersprachen stattfinden, wieder hinsichtlich der Entstehung eines Browsergames. Dies ist kein allgemeiner Vergleich und teils eine subjektive Meinung.
Des weiteren geht es um die Erschaffung eines OpenSource-Browsergames. Mit der Architektur stellt sich auch die Frage der richtigen Programmiersprache, die für diesen Fall am besten geeignet ist.
Die Platform ist für den Client – den Spieler – sein Browser, somit eine Website oder gar WebApplication. Hier steht nur eine Sprache zur Wahl: JavaScript. (Ich hasse Flash).
JavaScript wird mittlerweile von entwickelten Engines optimiert und sogar teils compiliert, auch größere Konstrukte sind im Browser möglich, es kann Rechenlast (Server->Client) ausgelagert werden.
Serverseitig ist die Auswahl größer. Letztlich lässt sich in fast jeder Sprache ein Server schreiben. Die meistverwendetsten sind wohl PHP, Java, Ruby, Python und Perl.
Java bleibt hier außen vor, und über Ruby (zu langsam) und Perl (zu häßlich) möchte ich nicht schreiben.
Entstehung:
JavaScript, PHP und Python hatten verschiedene Entstehungsbedingungen und Intentionen, sind daher auch für verschiedene Aufgaben geeigneter.
- PHP: Hypertext-Preprocessor. Als Templatesprache gedacht und dann für Webprogrammierung ausgeweitet.
- Python: Für besonders gute Lesbarkeit entwickelt. Allzwecksprache.
- JavaScript: Mehr Möglichkeiten zur Benutzerinteraktion auf Websites, HTML und CSS sind nicht turingvollständig. Komplizierte Entwicklung.
Zuletzt ist JavaScript stark beeinflusst durch den Browserkrieg. PHP ist etabliert, Python ist einfach schön.
Stil:
Prozedural, funktional, objektorientiert – das können alle drei, wobei prozedurale Programmierung in Python wohl Missbrauch wäre und PHP objektorientierte und funktionale Aspekte vor nicht allzu langer Zeit gelernt hat. JavaScript kommt mit einem minimalen Wortschatz aus und ist zudem klassenlos, kann aber Klassen ohne viel Aufwand nachbilden. Für mich ist ordentliche Objektorientierung wichtig. Der Prototypenbasierte Ansatz bei JavaScript gefällt mir.
Bedingungen:
Bei einem Browsergame ist eine Menge Kommunikation von Programmen erfordlich (Client-Server), besonders wenn es ein verteiltes System werden soll. Wobei jeder Server zumindest 100-1000 Spieler gleichzeitig aushalten sollte.
Platform:
PHP wird meist über (FastCGI) an einen Apachen oder anderen Webserver angebunden, der für jede Anfrage einen neuen Thread aufgemacht, der die Anfrage dann verarbeitet. Ein Thread hat jeweils einen eigenen Adressraum, teil sich keinen Arbeitsspeicher mit den anderen Threads. Für 100-1000 simultane Spieler braucht man dann halt einen leistungsstärkeren und teureren Server. Gleichzeitig konkurieren die Threads die ganze Zeit um die Datenbank.
NodeJS unterscheidet sich deutlich in der Architektur, welche aus dem Browser abstammt. Es gibt zwar die Möglichkeit Arbeit in Threads auszulagern, die sollte aber normalerweise nicht notwendig sein. Die Verarbeitung von Requests erfolgt ereignisgesteuert, Timeouts und Events werden von einer Schleife ausgeführt, die die ganze Zeit läuft (ein einziger Prozess). Abfragen mit verknüpfter Wartezeit (Datenbank, Dateisystem) werden asynchron ausgeführt. Während gewartet wird, widmet sich der Prozess eventuell bereits der nächsten HTTP-Anfrage.
Auch kommt hier eine Möglichkeit hinzu, die mir bei PHP gar nicht in den Sinn kam: Alle Requests teilen sich einen Adressraum und können auf den selben Arbeitsspeicher bzw. die selben Objekte im Code zugreifen. Deadlocks sind relativ unproblematisch, weil eh nur eine Anfrage zur Zeit verarbeitet wird. Natürlich gibt es Bibliotheken die auch für PHP Objekte im RAM cachen können, doch insgesamt gestaltet es sich deutlich einfacher in NodeJS. Das Array einfach eine Scope-Ebene drüber deklariert, und schon können alle darauf zugreifen. Ich plane die Datenbank komplett im RAM zu halten und alle paar Sekunden eine Schreiboperation an eine simple Datenbank zu schicken, die die Objekte versioniert (so kann dann im Falle eines Absturzes das Spiel wiederhergestellt werden).
Python ist auch in der Lage Objekte über den Applicationscope zu teilen.
Verbreitung:
Deutlich für PHP und Python spricht ihr Alter und ihre Verbreitung. Doch NodeJS ist gut dabei bald in die selbe Liga aufzusteigen. Gerade auch mit dem Cloud-Hype wird NodeJS immer beliebter. Ein kleiner Server mit NodeJS ist in der Amazon Cloud schnell installiert, aufrüsten gestaltet sich deutlich einfacher als auf einem normalen Server.
Frameworks:
Frameworks bilden sich für NodeJS erst langsam, da ist bei PHP und Python schon deutlich mehr Auswahl und Umfang enthalten. Mit Frameworks lässt sich natürlich Arbeit sparen, andererseits bläht es das System aber auch unnötig auf. Wieso ein großes Framework verwenden, wenn man denn doch nur einen kleinen Teil der Funktionalität braucht.
Fazit:
Es gibt keinen eindeutigen Sieger. Für mich selbst hat PHP allgemein verloren, weil ich an seine Grenzen gestoßen bin. Mit Python lässt sich in diesem Fall auch arbeiten, aber dann müssen Server- und Clientseite separat implementiert werden. NodeJS unterscheidet sich vor allem in der Herangehensweise und grundsätzlich in der asynchronen Architektur, da ist erstmal umdenken angesagt, wenn man vorher nur synchron programmiert hat.