måndag 31 maj 2010

Ladda php-klasser först när de ska användas

Idag var jag på Optimera STHLM och lyssnade på flera intressanta föreläsningar. Det var inte jättemycket nytt under solen men inspirerade till att optimera sin kod än mer och kändes som ett väldigt bra initiativ av IIS.

En oväntad sak jag lärde mig var att php har en inbyggd funktion som talar om hur mycket minne ens php-script allokerat som mest under exekveringen, nämligen: memory_get_peak_usage()

Jag var såklart tvungen att testa denna funktion på Pusha där jag blev glatt överraskad av att Pusha som mest verkar använda 4mb minne. Till min förvåning visade det sig att Qvaq använde mer minne än vad Pusha gör vilket var väldigt märkligt eftersom Pusha består av betydligt fler klasser. Efter ett tag insåg jag dock att det beror på att vi på Pusha laddar in endast de klasser som verkligen används dynamiskt istället för att ladda alla klasser hela tiden.

I vanliga fall kanske ens php-kod innehåller ett stort antal include-satser för att ladda in alla klasser man behöver, det kan se ut ungefär såhär (fast med hundratals rader):

include "classes/User.php";
include "classes/Link.php";
include "classes/Comment.php";

För att istället ladda in en klass först när den behövs om den behövs över huvud taget så behöver man bara override:a funktionen __autoload().

Denna funktion anropas automatiskt i php så fort php stöter på en klass som den inte känner till och skickar med namnet på den saknade klassen som inparameter. Det enda du behöver göra i funktionen är alltså att inkludera den fil där klassen som saknas är definierad. Enklast tänkbara sätt att göra detta är såhär:

function __autoload($class) {
   include "classes/".$class.".php";
}

På Qvaq sänkte dessa förändringar minnesanvändningen med 0,5mb per sidladdning från 4,25mb till 3,75mb. Kanske ingen jättevinst men då innehåller inte Qvaq speciellt många klasser och har man många requests kan det bli en hel del sparat minne.

Jag misstänkte att detta sätt att ladda in klasserna on-the-fly skulle göra att koden exekverades långsammare men enligt mina mätningar gick det lika snabbt eller möjligen till och med något snabbare.

Inga kommentarer:

Skicka en kommentar