25/02/2012

Utilisez un moteur javascript en PHP et faites exploser vos perfs

Bon, je l'admets, ce titre est un brin accrocheur et trolleur :-) . Ceci dit, je viens de tomber sur Twitter sur un package PECL que je ne connaissais pas et qui à mon avis ouvre des perspectives très intéressantes, notamment pour améliorer les performances de certaines fonctionnalités chronophage de PHP.

Sur certains de mes tests (voir plus bas), le résultat est juste... 300 fois plus performant !

Ce package, V8JS, permet d'utiliser dans PHP le célèbre V8 JavaScript Engine. Ce moteur, développé par Google et très performant, est le moteur javaScript de Chrome.

Installation du V8 JavaScript Engine

On va commencer par installer le moteur en lui-même :

sudo apt-get install libv8-dev
<p>sudo apt-get install libv8-3.1.8.22

Installation du package pear

sudo pecl install v8js-beta php_ini=/chemin/vers/le/php.ini

Puis modifier le php.ini pour inclure le module v8js.so

[v8js]
<p>extension=/chemin/du/module/v8js.so

Vous pouvez déplacer le module v8js.so dans le dossier des modules de PHP, ce qui permet d'avoir plus simplement :

<p>extension=v8js.so

Un petit phpinfo() pour vérifier :

phpinfo du moteur Javascript V8 en PHP

Utiliser V8JS

les choses sérieuses commencent ! Examinons la documentation. Plutôt simple : on a une classe V8Js, et une méthode executeString() pour appeler le moteur :

$v8 = new V8Js();
$JS = <<<EOT
function car(){
}
var myCar = new car();
<p>myCar.color = 'green';</p>
print(myCar.color);
<p>EOT;</p>

<p>try {</p>
  $v8->executeString($JS);
} catch (V8JsException $e) {
  var_dump($e);
}

On a donc utilisé le moteur javascript pour :

  • déclarer une classe
  • instancer un objet
  • ajouter un attribut à cette instance

Les performances

C'est là qu'on tombe dans des choses intéressantes.

Parenthèse :

Attention, comme tout bench, ces mesures sont à remettre dans leur cadre. ici je teste un type de comportement, dans un contexte donné, sur ma machine. De plus c'est orienté, j'ai délibérément choisi quelque chose pour lequel JavaScript excelle.

Bref, en voyant ça, je me suis dit : tiens, et si je testais un peu les performances ? J'ai alors cherché un comportement pour lequel JavaScript est particulièrement performant, et qui existe également en PHP. J'ai tout de suite pensé aux fonctions array_reduce / reduce. Voici deux codes qui me semblent comparables.

Voici le premier, en PHP pur :

<?php
// bench
$start = microtime(true);

//
// Test
$myArray = array();
for ($i = 0; $i < 100000; $i++) {
    array_push($myArray, $i);
}

function rsum($v, $w) {
    $v += $w;
    return $v;
}

$r = array_reduce($myArray, "rsum");

//
// Bench
$duration = microtime(true) - $start;
<p>var_dump($duration);

Dans l'autre, on reporte les calculs sur le moteur JavaScript :

//
// bench
$start = microtime(true);

$js = <<<EOT
<p>var i;</p>
<p>var myArray =  [];</p>
for (i = 0; i < 100000; i++) {
    myArray.push(i);
}

function rsum(v, w) {
    v += w;
    return v;
}

var r = myArray.reduce(rsum);
print(r);
<p>EOT;</p>


//
// Test
$v8 = new V8Js();
<p>try {</p>
  $v8->executeString($js);
} catch (V8JsException $e) {
  var_dump($e);
}

les résultats

Voici ce que j'obtiens :

  • en pur PHP : 2.5989
  • en reportant sur le moteur javascript : 0.0085

Bref, comme je le disais plus haut : un sacré écart !

Conclusion sur le moteur V8 en PHP

je n'ai aucun recul sur cette utilisation du moteur V8 au sein de PHP. Le package est d'ailleurs en bétâ. Cependant, je pense que c'est une piste sérieuse si on cherche à reporter certains traitements (particulièrement des calculs) vers JavaScript...

blog comments powered by Disqus