Performance: Arrays gegen Konstanten

Gestern ist mir aufgefallen, dass es in PHP von Haus aus ziemlich viele Konstanten für alle möglichen Funktionen gibt, die man ggf. nie in seinem Leben braucht. Diese Konstanten sind ja allerdings, wie der Name auch schon irgendwie sagt, immer da. Also habe ich mir gedacht, dass Konstanten dann ja gar nicht viel Speicher verbrauchen dürfen. Also habe ich mal ein wenig probiert …

Bei komplexer Programmierung hat man immer wieder Einstellungen, Parameter, etc., die oft im Programm benutzt werden und die deshalb irgendwo zentral abgelegt werden sollen. Prinzipiell stehen einem da ja in PHP drei Varianten zur Verfügung:

  • Variablen
  • Arrays
  • Konstanten

Variablen empfinde ich immer als sehr ungünstig, da diese nicht in Funktionen zur Verfügung stehen, es sei denn, man gibt sie als Parameter mit hineinen, oder holt sie über global $xxx nach, was ich sehr unsauber finde. Variablen scheiden also für mich für so „feste“ Werte aus.

In Arrays (bzw. Hashs) lassen sich die Daten sehr „ordentlich“ ablegen (und wiederfinden). Man kann Werte gruppieren, was sehr praktisch und übersichtlich ist. Allerdings gilt für Arrays die gleiche „Gültigkeit“ in Funktionen, wie für Variablen. Also nutze ich sie auch nur sehr selten für „feste“ Einstellungen/Werte.

Es bleiben noch die Konstanten. In der Regel definiert man Sie in GROSSBUCHSTABEN. Ich finde sie eigentlich sehr „klobig“ und nicht so dolle. Warum weiß ich nicht genau, sie haben mich halt immer irgendwie abgeschreckt. Der Vorteil ist ganz klar und einfach: Einmal definiert gelten Konstanten überall (und somit auch in jeder Funktion).

Das war die Grundtheorie, kommen wir nun zur Praxis. Ich wollte wissen wie es sich auswirkt, wenn man Arrays gegen Konstanten im Geschwindigkeits-/Speicherverbauchs-Vergleich (ein tolles Wort) antreten lässt.
Ich habe dazu zwei gleich aufgebaute Funktionen geschrieben:

Für Arrays:

$intTimeStart = time();

ob_start();

$arr = array();

for($i = 0; $i < 500000; $i++) {

	$arr['TEST' . $i] = rand(1000, 9999);

}

for($i = 0; $i < 500000; $i++) {

	echo $arr['TEST' . $i] . "\n";

}

ob_clean();

echo "\n\n" . memory_get_peak_usage() / 1024 / 1024 . " MB\n\n";
echo "\n\n" . time() - $intTimeStart . " Sekunden\n\n";

Für Konstanten:


$intTimeStart = time();

ob_start();

for($i = 0; $i < 500000; $i++) {

	define("TEST" . $i, rand(1000, 9999));

}

for($i = 0; $i < 500000; $i++) {

	echo constant("TEST" . $i) . "\n";

}

ob_clean();

echo "\n\n" . memory_get_peak_usage() / 1024 / 1024 . " MB\n\n";
echo "\n\n" . time() - $intTimeStart . " Sekunden\n\n";

Das Ergebnis ist sozusagen erschreckend! Hier die Ausgabe der Konstanten-Test-Funktion*:

2.44011306763 MB

2 Sekunden

Knapp 2,5 MB - schon nicht schlecht.

Und nun das Ergebnis der Array-Test-Funktion*:

44.5590744019 MB

2 Sekunden

Ich bin sprachlos. Kommentare?


* Auf einer Linux-Maschine ohne Last und nach mehreren Versuchen. Also ein subjektiver Durchschnittswert.

War dieser Artikel hilfreich für Sie?
[Gesamt: 0 Durchschnitt: 0]

4 thoughts on “Performance: Arrays gegen Konstanten

  1. awokenMIND sagt:

    Doch schon ein großer Unterschied. Da sieht man mal, wieviel Speicher man sich durch die Verwaltungsinformationen für Dynamik verbrät! Erstaunlich finde ich aber, dass die Laufzeit sich nicht bzw nur kaum ändert (Mikro-Timing). Bei den etlichen Array-Adressierungen hätte ich mir das schon deutlicher vorgestellt!

    In der Realität aber doch recht belanglos. Wer definiert/nutzt schon 500.000 Variablen/Konstanten und regt sich DANN über lächerliche 50MB RAM auf? Das oft kritisierte schlechte Laufzeitverhalten bei Array-Nutzung hingegen scheint hier zumindest in der Praxis als eher irrelevant degradiert worden zu sein.

  2. Ronald sagt:

    Hi awokenMIND,

    klar ist das natürlich ein Beispiel was fernab jeglicher Realität ist. Aber wenn ich ein Beispiel mit 100 Konstanten/Indizes genommen hätte, dann wäre der Unterschied kaum sichtbar gewesen. Mir ging es auch gar nicht so darum die Arrays zu verteufeln (bestimmt nicht), sondern vor allem um meine Neugierde zu befriedigen, ob es wirklich keine „Verschwendung“ ist, dass jede Hinz- und Kunz-Standard-PHP-Funktion mit einem Sack voll Konstanten daher kommt – und das bei jedem Interpreter-Start. :-)

  3. nukey sagt:

    konstants are konstants – they have no possibilities to interact with them. each and every array-entry is an object for itself – and maybe constants really get pre-parsed in a way we know it from c, so the memory-usage is as low as their values..

  4. […] habe ich ja schon die Auswirkungen von Konstanten mit Arrays in Bezug auf Speicherverbrauch verglichen. Nun ist es wieder Zeit für neue […]

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *