Optimierung überflüssiger Arrays in PHP
Nehmen wir an, ein Programmierer hat die Aufgabe,
die Summe der ganzen Zahlen von 1 bis 100000000 zu finden.
Unser Programmierer hat eine elegante Lösung für diese Aufgabe geschrieben, und zwar so:
<?php
echo array_sum(range(1, 100000000));
?>
Eine hübsche Lösung, nicht wahr? Nur eine Zeile und so weiter. Aber sie funktioniert nicht! Versuchen Sie, diesen Code auszuführen, und er wird einen Fehler anzeigen, dass Sie zu viel Arbeitsspeicher angefordert haben.
Hmm, 100000000 scheint nicht so viel zu sein?
Oder doch? Rechnen wir nach. Die Funktion range
erzeugt ein Array mit 100000000 Zahlen.
Nehmen wir an, PHP weist für eine Zahl 2 Bytes
zu - dann würde für die Speicherung unseres Arrays
200000000 Byte benötigt, also etwa
200 Megabyte Arbeitsspeicher.
Tatsächlich wird jedoch viel mehr Arbeitsspeicher
benötigt, weil PHP sehr hohe Overhead-Kosten bei der
Speicherung von Arrays hat.
Zum Beispiel steht in meiner Fehlermeldung,
dass ich versuche, 4294967304
Byte zuzuweisen - das sind etwa 4 Gigabyte!
Es ist jetzt klar, warum der Fehler auftritt - wir haben die erlaubte Speichergrenze bei weitem überschritten.
Es ist nicht schwer, unser Skript in eines umzuschreiben, das praktisch keinen Arbeitsspeicher verbraucht:
<?php
$sum = 0;
for ($i = 1; $i <= 100000000; $i++) {
$sum += $i;
}
echo $sum;
?>
Oder noch besser, wir verwenden die mathematische Lösung:
<?php
$n = 1000000;
$sum = $n * ($n + 1) / 2;
echo $sum;
?>
Ein Programmierer hatte die Aufgabe, die Fakultät einer gegebenen Zahl zu finden. Er löste sie wie folgt:
<?php
$n = 100;
echo array_product(range(1, $n));
?>
Erklären Sie, was an diesem Code nicht stimmt. Schreiben Sie den Code in eine optimiertere Version um.
Ein Programmierer hatte die Aufgabe, die Anzahl
der Ziffern zu finden, die benötigt werden, um
alle ganzen Zahlen von 1 bis 1000000 zu schreiben.
Er löste sie wie folgt:
<?php
echo strlen(implode('', range(1, 1000000)));
?>
Erklären Sie, was an diesem Code nicht stimmt. Schreiben Sie den Code in eine optimiertere Version um.
Ein Programmierer hatte die Aufgabe, die Anzahl
der Zahlen zu finden, die ohne Rest durch
7 teilbar sind und in einem gegebenen
Intervall liegen. Er löste sie wie folgt:
<?php
$arr = [];
for ($i = 0; $i <= 1000; $i++) {
if ($i % 7 == 0) {
$arr[] = $i;
}
}
echo count($arr);
?>
Erklären Sie, was an diesem Code nicht stimmt. Schreiben Sie den Code in eine optimiertere Version um.
Ein Programmierer hatte die Aufgabe, die Summe der Teiler einer Zahl zu finden. Er löste sie wie folgt:
<?php
$num = 320;
$divs = [];
for ($i = 0; $i <= $num; $i++) {
if ($num % $i == 0) {
$divs[] = $i;
}
}
echo array_sum($divs);
?>
Erklären Sie, was an diesem Code nicht stimmt. Schreiben Sie den Code in eine optimiertere Version um.