Aujourd’hui nous allons voir la suite de l’optimisation Zend. Je sais, ça fait un moment que je devais le faire mais là j’ai le temps.

Pour ce tutoriel je suis sur un unbuntu 10.04 LTS avec PHP5.3.2 et avec le cache APC activé. Les résultats que vous verrez povienne de tests sur mon site perso en temps réel en local afin que vous vous fassiez une idée sur la consommation d’un site vers la fin de son développement de la taille du mien.

Nous allons donc voir aujourd’hui la consommation mémoire de chacune de vos pages ou plutôt de vos actions, via un fichier de log généré par Zend. Ce log est généré par une fonction intégrée au bootstrap de votre projet. Je vais vous enseigner comment le mettre en place.

Nous verrons à la fin la charge mémoire du site avec les require_once laissés dans la library Zend (voir poste précédant) puis en les enlevant pour voir s’il y a une réelle différence.

La taille d’allocation mémoire calcule juste la mémoire utilisée par PHP dans le chargement des classes, données et l’exécution de vos scripts. Elle n’a rien à voir avec les images qui composent votre site.

Pour commencer, nous avons besoin du plugin Zend effectuant toute la partie traitement:

class App_Controller_Plugin_MemoryPeakUsageLog extends Zend_Controller_Plugin_Abstract
{
    protected $_log = null;

    public function __construct(Zend_Log $log)
    {
        $this->_log = $log;
    }

    public function dispatchLoopShutdown()
    {
        //récupère l'usage de mémoire utilisé réellement par PHP
        $peakUsage = memory_get_peak_usage(true);
        //on récupère l'url de la page en cours
        $url = $this->getRequest()->getRequestUri();
        //on stoque tout sa dans notre fichier de log avec le statut info
        $this->_log->info($peakUsage . ' bytes ' . $url);
    }
}

Et pour finir voici la fonction à ajouter dans notre bootstrap afin d’exécuter ce plugin automatiquement pour chaque page:

protected function _initEnableMemoryUsageLogging()
{
    //initialisation d'un fichier de log
    //il doit exister pour être utilisé.
    $writer = new Zend_Log_Writer_Stream(
    APPLICATION_PATH . '/logs/memory_usage');
    //création d'un log rattaché à notre fichier précédemment iinitialisé
    $log = new Zend_Log($writer);
    //on appelle un plugin s'occupant de tout ce traitement
    $plugin = new App_Controller_Plugin_MemoryPeakUsageLog($log);

    /**
     * Si vous mettez votre plugins avant tous les autres, ils seront
     * pris en compte dans le calcul de mémoire.
     */
    $frontController = $this->getResource('frontController');
    //on enregistre le plugin
    $frontController->registerPlugin($plugin);
}

Normalement, en allant sur la page d’index de votre page, le fichier memory_usage devrait avoir la ligne suivante:

2010-05-24T16:07:23+02:00 INFO (6): 20971520 bytes /throrinstudio/</code> 

La valeur affichée en bytes équivaut à 20 Mo environ. Si vous refaites un chargement de cette page, la mémoire a diminuée, ceci grâce au cache APC de PHP:

2010-05-24T16:08:33+02:00 INFO (6): 6291456 bytes /throrinstudio/

La valeur ici équivaut à 6,2 Mo environ. Maintenant nous enlevons les require_once de la library Zend et nous effectuons un autre test (il y a encore le cache APC) :

2010-05-24T17:09:27+02:00 INFO (6): 6029312 bytes /throrinstudio/

Ceci équivaut à 6 Mo. La différence n’est pas énorme mais mon site utilise peu de classes Zend. Si vous prenez un gros site intégrant Zend_AMF, Zend_DB et d’autres aussi gourmands, vous aurez une plus grande différence qu’ici. Idem si vous n’utilisez pas le cache APC. En purgeant le cache, j’arrive à la valeur suivante lors du premier chargement:

2010-05-24T17:09:16+02:00 INFO (6): 19922944 bytes /throrinstudio/

Ici, ça nous fait 19 Mo. Si nous regardons ce résultat par rapport au premier, nous arrivons à une différence de 1 Mo d’utilisation mémoire.

En conclusion, cette partie n’est pas vraiment une optimisation. Elle sert surtout à voir l’utilisation mémoire de votre site. Vous pouvez constater la différence d’utilisation mémoire avec et sans le cache APC. Cette différence est tout de même énorme (14 Mo dans l’exemple).