Diese Woche habe ich mich mit einem kleinen Performance Problem im Vergleichsrechner zur Gebäudeversicherung der iak! GmbH beschäftigt. Durch die wirklich enorme Datenmenge, die vom Vergleichsrechner benötigt wird, sank die Performance mit jedem neuen Update immer mehr. So benötigte der Vergleichsrechner zur Berechnung eines umfangreichen Ergebnisses teilweise schon Sekunden. Ja gut, ein paar Sekunden mag jetzt so manch einer denken. Aber schnell geht irgendwie auch anders. Ein Glück gibt es die SPL, die seit PHP 5.3 auch sehr brauchbare Klassen zum Handling von Datenstrukturen bereit stellt.
Macht es überhaupt Sinn die SPL zu nutzen?
Es kommt drauf an! Grundsätzlich macht es schon Sinn die Möglichkeiten der SPL zu nutzen. Einerseits programmiere ich fast ausschließlich in einem objektorientierten Umfeld. Warum also nicht die Klassen nutzen, die PHP bereits mitbringt? Da der Vergleichsrechner auch mit unwahrscheinlich vielen Daten umgehen muss, ist der Einsatz von SPL Datenstrukturen sogar noch sinnvoller, da es hier Vorteile bei der Performance und beim Speicherverbrauch geben kann. Tobias Schlitt hat hier ein kleines Benchmark zur SplHeap Klasse im direkten Vergleich zur einfachen Sortierung eines Arrays mit entsprechenden Funktionen erstellt.
Große Datenmengen mit SplHeap sortieren
Nun kommen wir zurück zu meinem Problem. Die Ergebnismenge des Vergleichsrechners muss nach errechneter Prämie absteigend sortiert ausgegeben werden. Bisher habe ich die Ergebnismenge mit array_multisort() sortiert. Hier lag ein ziemlicher Flaschenhals. Eher Zufällig bin ich dann auf SplHeap gestoßen. SplHeap ist eine abstrakte Klasse, welche nicht direkt aufgerufen werden kann. SplMaxHeap und SplMinHeap sind zwei direkte Ableitungen, die die übergebenen Werte entweder auf- oder absteigend sortieren. Anhand des folgenden Beispiels möchte ich dies mal ein wenig verdeutlichen.
class MyHeap extends SplMinHeap {
public function compare(ArrayObject $objA, ArrayObject $objB) {
return $objB->preis - $objA->preis;
}
}
$objA = new ArrayObject(
array(
'preis' => 299.90,
'name' => 'Produkt A'
),
ArrayObject::ARRAY_AS_PROPS
);
$objB = new ArrayObject(
array(
'preis' => 199.95,
'name' => 'Produkt B'
),
ArrayObject::ARRAY_AS_PROPS
);
$objC = new ArrayObject(
array(
'preis' => 599.75,
'name' => 'Produkt C'
),
ArrayObject::ARRAY_AS_PROPS
);
$heap = new MyHeap();
$heap->insert($objA);
$heap->insert($objB);
$heap->insert($objC);
// Ausgabe: Produkt B : 199.95 Produkt A : 299.9 Produkt C : 599.75
foreach ($heap as $product) {
echo $product->name . ' : ' . $product->preis . PHP_EOL;
}
Fazit: Der Vergleichsrechner ist nun wieder etwas schneller und SplHeap arbeitet wirklich ein wenig schneller, als die zuvor genutzte einfache Array Sortierfunktion.