In questo breve post vi mostrerò come misurare le performance del vostro codice Magento, in modo tale da capire quali sono le parti che richiedono più memoria o tempi di caricamento lunghi; in base a questo riuscirete a scovare questi “buchi neri” del codice e quindi ad evitare tutto ciò che rende gli e-commerce lenti, poco usabili e poveri in termini di vendite.
La piattaforma Magento ha preinstallato di default il profiler di sistema, ovvero un tool che se attivato mostra il tempo che impiegano le varie chiamate e la memoria che queste utilizzano.
Per attivare il profiler è necessario andare in Sistem -> Configuration -> Advanced -> Developer -> Debug -> Profiler ed impostarlo a Yes.
Andate poi nel vostro index.php nella root del magento e decommentate la linea Varien_Profiler::enable();.
Questa istruzione abiliterà il profiler di magento che apparirà in ogni pagina sotto al footer, ecco a voi uno screenshot del profiler:
Esistono casi in cui volete testare le performances solamente di alcune chiamate o parti di codice, per capire l’impatto che queste avranno sul vostro sito o sulla velocità di risposta; come fare in questi casi?
La soluzione è uno script Magento (passatemi il termine) con incorporato il profiler magento che analizza le chiamate ed il vostro codice.
Ecco qua l’esempio di codice che carica alcuni ordini e mostra i risultati a schermo:
[sourcecode language=”php”]
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
require_once ‘app/Mage.php’;
Varien_Profiler::enable();
$app = Mage::app(”);
try {
Varien_Profiler::start(‘Profiler::Load::Order’);
$read = Mage::getSingleton(‘core/resource’)->getConnection(‘core_read’);
$value = $read->query("SELECT * from catalog_product_entity");
$results = $value->fetchAll();
foreach ($results as $res) {
$order = Mage::getModel("sales/order")->load($res["entity_id"]);
}
Varien_Profiler::stop(‘Profiler::Load::Order’);
$timers = Varien_Profiler::getTimers();
#$out = ‘<div style="position:fixed;bottom:5px;right:5px;opacity:.1;background:white" onmouseover="this.style.opacity=1" onmouseout="this.style.opacity=.1">’;
#$out = ‘<div style="opacity:.1" onmouseover="this.style.opacity=1" onmouseout="this.style.opacity=.1">’;
$out = "<h1>Profiler</h1>";//"<a href=\"javascript:void(0)\" onclick=\"$(‘profiler_section’).style.display=$(‘profiler_section’).style.display==”?’none’:”\">[profiler]</a>";
$out .= ‘<div id="profiler_section" style="background:white; display:block">’;
$out .= ‘<pre>Memory usage (bytes): real: ‘ . memory_get_usage(true) . ‘, emalloc: ‘ . memory_get_usage() . ‘</pre>’;
$out .= ‘<pre>Memory usage (Mega): real: ‘ . doubleval(memory_get_usage(true) / 1048576) . ‘, emalloc: ‘ . doubleval(memory_get_usage() / 1048576) . ‘</pre>’;
$out .= ‘<table border="1" cellspacing="0" cellpadding="2" style="width:auto">’;
$out .= ‘<tr><th>Code Profiler</th><th>Time</th><th>Cnt</th><th>Emalloc</th><th>RealMem</th></tr>’;
foreach ($timers as $name => $timer) {
$sum = Varien_Profiler::fetch($name, ‘sum’);
$count = Varien_Profiler::fetch($name, ‘count’);
$realmem = Varien_Profiler::fetch($name, ‘realmem’);
$emalloc = Varien_Profiler::fetch($name, ‘emalloc’);
if ($sum < .0010 && $count < 10 && $emalloc < 10000) {
continue;
}
$out .= ‘<tr>’
. ‘<td align="left">’ . $name . ‘</td>’
. ‘<td>’ . number_format($sum, 4) . ‘</td>’
. ‘<td align="right">’ . $count . ‘</td>’
. ‘<td align="right">’ . number_format($emalloc) . ‘</td>’
. ‘<td align="right">’ . number_format($realmem) . ‘</td>’
. ‘</tr>’
;
}
$out .= ‘</table>’;
$out .= ‘<pre>’;
$out .= print_r(Varien_Profiler::getSqlProfiler(Mage::getSingleton(‘core/resource’)->getConnection(‘core_write’)), 1);
$out .= ‘</pre>’;
$out .= ‘</div>’;
$totalTime = 0;
foreach ($timers as $timer => $ti) {
$sum = Varien_Profiler::fetch($timer, ‘sum’);
$totalTime = doubleval($totalTime) + doubleval($sum);
}
echo $out . "<br/><br/>";
echo "Execution time in seconds: " . $totalTime;
} catch (Exception $e) {
echo $e->getMessage();
Mage::printException($e);
}
?>
[/sourcecode]
Questo è il risultato dello script; come potete notare la parte incapsulata dentro le chiamate “Start” e “Stop” del profiler è quella che si occupa di racchiudere tutte le chiamate che vengono fatte al suo interno (nel nostro esempio la query degli ordini ed il loro caricamento). Il risultato nel profiler avrà il nome passato al profiler ovvero Varien_Profiler::stop(
'Profiler::Load::Order'
);