Rolf B: Tipps für die Verwendung von Array oder Objekt

Beitrag lesen

Hallo MB,

resourcenfressendes Objekt

dazu ein Nachtrag. PHP Arrays sind, wie zitiert, geordnete Maps. Das ist auch keine triviale Struktur. Aber man kann ja messen.

Das folgende Beispiel verwendet wahlweise ein Objekt oder ein Array, um ein paar Werte zu speichern. Ich rechne ein bisschen rum damit der PHP Compiler nichts wegoptimiert. Die erzeugten Objekte bzw. Arrays werden in einem Array gesammelt, um den Speicher messen zu können.

(Edit 12:38 Uhr: Elemente in $buf[$i] speichern statt in $f)

class Foo {
    public $bar, $baz, $fup, $hup, $bup;
    function __construct($t) {
        $this->bar = $t+1;
        $this->baz = $t+2;
        $this->fup = $t+3;
        $this->hup = $t+4;
        $this->bup = $t+5;
    }
}

$start = microtime(TRUE);
$m0 = memory_get_usage();

$buf = [];

for ($i=0; $i<10000; $i++)
{
    $buf[$i] = new Foo($i);
//  $buf[$i] = [ "bar" => $i+1, "baz" => $i+2, "fup" => $i+3, "hup" => $i+4, "bup" => $i+5 ];
}

$memory = (memory_get_usage()-$m0)/1024;
$time = (microtime(TRUE) - $start)*1000000;

echo "Laufzeit: $time µs, Speicher: $memory KB";

Die leere Schleife braucht 100µs, und die Laufzeit mit Inhalt variiert auf PHP Sandbox von 1200 bis 2000 Mikrosekunden, egal welche Zeile ich in die Schleife einkommentiere. Es sind 10000 Durchläufe, d.h. die Erzeugung eines Objekts oder eines Arrays liegt im Bereich von 160±40 Nanosekunden.

Das ist für alle Anwendungszwecke, mit denen wir hier zu tun haben, komplett zu vernachlässigen. Du musst Dich also bei deinen Überlegungen für Objekt oder Array nicht von Performancefragen leiten lassen.

Anders ist es beim Speicher. Die Array-Version erhöht den von memory_get_usage gelieferten Wert um 4187 KB, also gut 4 Megabytes. Die Objektversion belegt dagegen 2198 KB, spart also ca die Hälfte.

Bei 10 statt 5 Properties wächst der Speicherbedarf bei Arrays auf 7312 KB und bei Objekten auf 2823 KB, d.h. der Preis pro Property ist bei Arrays höher als bei Objekten. Die Namenslänge der Properties spielt dagegen keine Rolle, weil PHP bei einem mehrfach verwendeten String nur Referenzen speichert.

Wichtig ist aber die PHP Version. Es kann zwar auch an den Sandbox-Servern liegen, aber PHP 7 ist deutlich schneller und auch effizienter bei Objekten. Die Durchlaufzeit der Testschleife stieg bei ältere PHP Versionen (vor 7) auf über 4000µs und war bei Objekten noch deutlich langsamer (6000µs und mehr). Ab PHP 7 nähern sich die Zeiten an und werden absolut betrachtet deutlich kleiner, mit einem leichten Vorteil für Arrays. Insbesondere halbiert sich bei PHP 7 der gemeldete Speicherbedarf - woran auch immer das liegt.

D.h. wenn Du aus irgendwelchen Gründen an PHP 5 festklebst, können Arrays in Hochlastsituationen Zeitvorteile bieten, erkauft mit deutlich höherem Speicherbedarf. Allerdings wäre in Hochlastsituationen eher eine andere Sprache angebracht, und sei es auch nur Hack und die HHVM statt PHP mit der ZEND Engine.

Rolf

--
sumpsi - posui - clusi