PHP: HHVM-Benchmark
Im Benchmarksgame schneidet PHP stets äußerst schlecht ab. Die Implementierung in C benötigt meist wenige Sekunden Ausführungszeit, wohingegen PHP stets mehrere Minuten den Rechner belastet. Was bringt da HHVM?
Ausgangssituation
In meinem letzten Blogbeitrag habe ich herausgefunden, dass durch HHVM im Falle der Applikation Serendipity keine erhebliche Beschleunigung erzielt wird, wenn man PHP in Verbindung mit XCache einsetzt.
Offensichtlich habe ich nicht den Anwendungsfall getroffen, für den HHVM einst gebaut wurde. Dann lasse ich es eben richtig rechnen. Am Binarytree-Benchmarksgame habe ich mich hierfür bedient.
Auf der dort vorliegenden Testumgebung benötigt PHP 5.5 satte elf Minuten und C etwa zehn Sekunden für den selben Algorithmus.
Testumgebung
Ich habe wieder meine Hiphop-VM gestartet, alle unnötigen Dienste deaktiviert und den Quellcode vom Binarytrees in eine PHP-Datei gesteckt. Beim ersten Ausführungsversuch mit PHP 5.3 wird mir trotz Speicherlimit von zwei Gigabyte die folgende Meldung ausgegeben.
hiphop@hiphop-test:~$ php -n -d memory_limit=2048M binarytrees.php 20 Fatal error: Allowed memory size of 2147483648 bytes exhausted (tried to allocate 73 bytes) in /home/hiphop/binarytrees.php on line 18
Ich verkneife mir jetzt jeglichen Kommentar und aktualisiere die PHP-Version auf 5.4, weil dort diesbezüglich optimiert wurde.
Es ist zu erwarten, dass mein Setup die beim Benchmarksgame angegebenen elf Minuten nicht exakt erreicht, da ich andere Hardware am Start habe.
Durchführung
Die Ausgabe des Benchmarkskripts binarytrees.php sieht stets wie folgt aus. Es wird also bei jedem Testlauf richtig gerechnet.
stretch tree of depth 21 check: -1 2097152 trees of depth 4 check: -2097152 524288 trees of depth 6 check: -524288 131072 trees of depth 8 check: -131072 32768 trees of depth 10 check: -32768 8192 trees of depth 12 check: -8192 2048 trees of depth 14 check: -2048 512 trees of depth 16 check: -512 128 trees of depth 18 check: -128 32 trees of depth 20 check: -32 long lived tree of depth 20 check: -1
Nun folgen die Ausführungszeiten ohne die Skriptausgaben.
PHP 5.4 mit Standardeinstellungen
Der Schalter n deaktiviert die php.ini und damit jegliche Extensions.
hiphop@hiphop-test:~$ time php -n -d memory_limit=2048M binarytrees.php 20 real 8m26.254s user 8m4.882s sys 0m21.217s
Die Zeit weicht wie erwartet ab, bewegt sich aber in gleichen Regionen.
PHP 5.4 mit XCache
Ohne den Schalter n wird nun auch auf XCache zurückgegriffen.
hiphop@hiphop-test:~$ time php -d memory_limit=2048M binarytrees.php 20 real 8m27.003s user 8m5.634s sys 0m21.201s
Die Zeit steigt minimal im Vergleich zur Standardeinstellung.
HHVM mit Standardeinstellungen
Es muss kein Speicherlimit gesetzt werden, weil HHVM in den Standardeinstellungen keines gesetzt hat.
hiphop@hiphop-test:~$ hhvm --version HipHop VM v2.1.0-dev (rel) Compiler: tags/HPHP-2.1.0-0-gee8da60efaad9398eb4fb5909ede5cf6bb662128 Repo schema: 56ccb9c5c4a45b351e042a3b4da0b98d7e4e27f9 hiphop@hiphop-test:~$ time hhvm binarytrees.php 20 real 4m34.108s user 4m33.741s sys 0m0.176s
Cool!
Zusatztest: PHP 5.5 mit eigenem OpCode-Cache
Um allen gerecht zu werden, habe ich auch einen Testlauf mit der aktuellsten PHP-Version gefahren. Ich setze den Schalter n nicht, damit die gesamte Zend-Magic in Betrieb ist. Früher hieß das Teil übrigens nicht einfach OPcache sondern Optimizer Plus.
hiphop@hiphop-test:~$ php -v PHP 5.5.1-1~precise+1 (cli) (built: Jul 22 2013 07:33:14) Copyright (c) 1997-2013 The PHP Group Zend Engine v2.5.0, Copyright (c) 1998-2013 Zend Technologies with Zend OPcache v7.0.2-dev, Copyright (c) 1999-2013, by Zend Technologies hiphop@hiphop-test:~$ time php -d memory_limit=2048M binarytrees.php 20 real 8m32.390s user 8m9.683s sys 0m22.509s
Bummer!
Ergebnis
PHP 5.3 ist ein Speicherschwein.
PHP 5.4 kommt mit zwei Gigabyte Speicherlimit aus und es ist irrelevant, ob XCache aktiviert ist. Es benötigt knappe 8,5 Minuten. XCache erzeugt unnötigen Overhead, weil es nie einen Cachehit erzeugen kann. Das Skript läuft eben exakt ein einziges Mal.
HHVM benötigt lediglich 4,5 Minuten. An dieser Stelle kommt der JIT voll zum Tragen. Ich habe mir eine erheblichere Beschleunigung gewünscht, aber eine knapp 50 prozentige Verkürzung der Ausführungszeit ist ein gutes Ergebnis.
PHP 5.5 braucht gute 8,5 Minuten und damit noch mehr Zeit als 5.4. Ich betrachte das als Reinfall.
Fazit
Wenn Ihr also langlaufende rechenintensive Prozesse in PHP benutzen müsst, probiert HHVM definitiv mal aus.
Kommentare