Micro-performance
Astuces et Indications sur l'exécution de scripts PHP
Quoi ?
La micro-performance, c'est :
- Simplifier un code pour diminuer le nombre d'opérations machine
- Réduire la complexité d'une application
- Optimiser l'architecture d'une application
- Conserver et améliorer la lisibilité pour l'humain
Pourquoi ?
- Économiser les ressources matérielles
- Stabiliser les applications
- Chargement plus rapide pour l'utilisateur
Comment ?
- Regarder sous le capot
- Se mettre à la place de la machine (cf. Freud)
- Penser KISS
- Voir KISS
- Manger KISS
Y'aura du cache
C'est la réponse de beaucoup d'acteurs du web, surtout sur les grosses applications. Le cache c'est comme le parfum, ça sent bon seulement quand on dose bien.
On rajoutera des machines
La prochaine fois que vous croiserez quelqu'un du service compta, je ne pourrai plus rien pour vous.
Mais après tout...
Un exemple de code à améliorer
$conn = $this->getEntityManager()->getConnection();
$qb = $conn->createQueryBuilder();
$qb->select("o.type")
->from("organization__organization", "o")
->where("o.{$column}=:organization_property");
$qb->setParameter("organization_property", $value);
$type = $qb->execute()->fetch();
Possibilité d'amélioration
$type = $this
->getEntityManager()
->getConnection()
->createQueryBuilder()
->select("o.type")
->from("organization__organization", "o")
->where("o.{$column}=:organization_property")
->setParameter("organization_property", $value)
->execute()
->fetch()
;
Gérer sa RAM
Comment ça fonctionne ?
Le moteur Zend utilise une unité de mémoire, la Zval. Elle contient :
- Un compteur de références
- Un booléen is_ref
- Une valeur

Les scopes
- Les variables initialisées dans le scope global sont en mémoire jusqu'à la fin du script.
- Les variables initialisées dans le scope local, à l'intérieur d'une fonction, sont supprimées dès la fin de la fonction.
- Une variable initiée dans le scope local mais faisant l'objet d'une référence extérieure ne sera pas supprimée à la fin de la fonction => risque de fuite de mémoire.
Les pièges

Les références circulaires

Solution I
class ParentTest {
protected $child;
public function __construct(){
$this->child = new ChildTest($this);
}
}
class ChildTest {
protected $parent;
public function __construct(ParentTest $parent) {
$this->parent = $parent;
}
}
Résultats Solution I

Solution II
class ParentTest {
// ...
public function __destruct(){
unset($this->child);
}
}
class ChildTest {
// ...
public function __destruct() {
unset($this->parent);
}
}
Résultats Solution II

Le Garbage Collector
- Tampon de racines (Root Buffer)
- Collecte les références inutilisées
- Assez lourd à l'exécution

Résultats Solution III

Temps d'Exécution

Les fonctions récursives

Exemple
function recursiveFunction($i) {
$object = new HeavyObject();
// Opérations sur $object
if($i % 10000 === 0) {
echo memory_get_usage() . '<br>';
}
if($i < 100000) {
$i++;
recursiveFunction($i);
}
}
Sortie
801600
12230496
23724864
34170656
46713600
57683208
68129000
82769096
93214888
104184496
Micro-Performance PHP
By Axel Venet
Micro-Performance PHP
Workshop sur les micro-performances en PHP et les moyens d'améliorer l'efficacité de notre code.
- 560