Scripts

Profiler

Met deze klasse (nouja, klasse, hij is nog static, wat in dit geval betekend dat je maar 1 instantie tegelijk kan draaien) kan je per regel van je code de tijd opnemen die de PHP parser erover doet, en hoe vaak de PHP parser eroverheen leest. De uitvoer kan ik niet echt verklaren omdat ik de interne werking van de PHP parser niet ken. Deze klasse is vooral handig om binnen grote bestanden van bijvoorbeeld een CMS de bottlenecks te vinden. Let niet op de tijden zelf, maar op de verschillen in tijd aangezien het profilen zelf ook nog aardig wat tijd in beslag neemt. De te profilen code zet je binnen een declare-lus. Voordat je die lus start roep je eerst Profiler::instantiate() aan zodat register_tick_function () aangeroepen wordt. Achteraf, dus na de lus roep je dan weer Profiler::printReport() aan om de uitvoer te (ver)krijgen. Deze klasse maakt gebruik van WebFX charts om een mooi beeld te genereren. Uiteraard kan je dat allemaal aanpassen naar tekst of een plaatje, wat je wilt. Maar wil je dit voorbeeld letterlijk overnemen, dan zal je dit zip-bestand moeten hebben en de nodige code opnemen alvorens er een grafiek verschijnt. Je kan ook even de bron vanmijn voorbeeld erbij pakken. (Het zou het mooist zijn als er aparte klassen waren voor de uitvoer, maar aangezien het voor mij maar een gewoon quick & dirty hulpmiddeltje is hechte ik daar niet zoveel belang aan.) Het beste resultaat krijg je met SQL-queries, XML, veel preg_* enzovoord aangezien die veel tijd innemen en die dus ook als eerste moeten worden nagelopen bij het optimaliseren van de code. Let op: Een declare-lus kan niet meerdere bestanden omvatten. Includes worden dus niet geprofiled, of in ieder geval, ik heb hem nog niet zover gekregen.

profiler
<?php
class Profiler {

   static protected $ticks = array();
   static protected $file = false;
   static private $buffer = 0;

   public function instantiate() {
      register_tick_function(array('Profiler', 'doSomethingWithTheTick'));
      self::$buffer = microtime(true);
   }

   static public function doSomethingWithTheTick() {
      $backtrace = debug_backtrace();
      if(!self::$file) {
         self::$file = $backtrace[0]['file'];
      }
      self::$ticks[$backtrace[0]['line']][] =  microtime(true) - self::$buffer;
      self::$buffer = microtime(true);
   }

   static public function getTicks() {
      return self::$ticks;
   }

   static public function printReport($return = false) {
      ksort(self::$ticks);

      $lines = array();
      $times = array();
      $rounds = array();

      $lines = array_keys(self::$ticks);
      foreach(self::$ticks as $time) {
         $times[] = round(array_sum($time) * 100, 5);
         $rounds[] = count($time);
      }

      $ouput = "
      <script type=\"text/javascript\">
         var c = new Chart(document.getElementById('chart'));
         c.setDefaultType(CHART_LINE);
         c.setGridDensity(" . count($lines) . ", 15);
         c.setHorizontalLabels([" . implode(', ', $lines) . "]);
         c.setShowLegend(true);
         c.add('Tijd', '#000000', [" . implode(', ', $times) . "]);
         c.draw();

         var d = new Chart(document.getElementById('chart2'));
         d.setDefaultType(CHART_LINE);
         d.setGridDensity(" . count($lines) . ", 15);
         d.setHorizontalLabels([" . implode(', ', $lines) . "]);
         d.setShowLegend(true);
         d.add('Rondes', '#FF0000', [" . implode(', ', $rounds) . "]);
         d.draw();
      </script>";
         if($return)
            return $ouput;
         else
            echo $output;
   }
}
?>
Voorbeeldcode:
<?php
require 'bovenstaandeKlasse.php';

Profiler::instantiate();

declare(ticks=1) {
 //hier je code
}

//geeft de javascript-code
Profiler::printReport();

//geeft de kale array
var_dump(Profiler::getTicks());

//geeft de javascript-code terug (return = true)
var_dump(Profiler::printReport(true));
?>

Reacties

0
Nog geen reacties.