Leçon 13 / 20

Reproduire une lenteur mesurable

25 min PHP 8 — architecture, tests et sécurité Gratuit

Objectif : Établir un scénario de recherche reproductible et relever son temps d’exécution initial.

Une recherche qui paraît rapide avec quelques contacts peut devenir lente lorsque le carnet contient beaucoup de données. Sans scénario contrôlé, vous ne pouvez pas distinguer une régression du simple effet d’une machine momentanément occupée. Vous allez créer une mesure répétable et conserver un temps initial, avant toute optimisation.

Définir un scénario comparable

Une mesure utile précise au moins le volume de données, la recherche exécutée, le nombre d’essais et l’environnement de test. Pour le carnet, le scénario ci-dessous crée 20 000 contacts temporaires dans une base SQLite en mémoire, puis cherche une adresse connue. Il n’ajoute aucune classe ou fichier au projet : exécutez-le comme une commande PHP autonome pour apprendre la méthode, puis appliquez le même protocole à la base de test du projet.

Mesurer la requête

Le programme crée les données avec des instructions préparées, puis lance une recherche sur le champ courriel. Il utilise hrtime(true), qui fournit une mesure monotone en nanosecondes adaptée à la durée écoulée. Une première exécution de la requête est écartée pour limiter l’effet d’initialisation ; les temps suivants sont triés et la médiane est affichée.

Scénario autonome à exécuter avec PHP 8.3PHP
<?php

declare(strict_types=1);

$pdo = new PDO('sqlite::memory:');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->exec(
    'CREATE TABLE contacts (
        id INTEGER PRIMARY KEY,
        nom TEXT NOT NULL,
        courriel TEXT NOT NULL,
        telephone TEXT NOT NULL
    )'
);

$insertion = $pdo->prepare(
    'INSERT INTO contacts (nom, courriel, telephone)
     VALUES (:nom, :courriel, :telephone)'
);

for ($numero = 1; $numero <= 20000; $numero++) {
    $insertion->execute([
        'nom' => 'Contact ' . $numero,
        'courriel' => 'contact' . $numero . '@exemple.test',
        'telephone' => '060000' . str_pad((string) $numero, 4, '0', STR_PAD_LEFT),
    ]);
}

$recherche = $pdo->prepare(
    'SELECT id, nom, courriel
     FROM contacts
     WHERE courriel = :courriel'
);
$courrielRecherche = '[email protected]';
$tempsEnMillisecondes = [];

for ($essai = 0; $essai < 11; $essai++) {
    $debut = hrtime(true);
    $recherche->execute(['courriel' => $courrielRecherche]);
    $contact = $recherche->fetch(PDO::FETCH_ASSOC);
    $duree = (hrtime(true) - $debut) / 1_000_000;

    if ($essai > 0) {
        $tempsEnMillisecondes[] = $duree;
    }

    if ($contact === false) {
        throw new RuntimeException('Le contact attendu est absent.');
    }
}

sort($tempsEnMillisecondes);
$mediane = $tempsEnMillisecondes[intdiv(count($tempsEnMillisecondes), 2)];

printf(
    "Contacts : 20000 | Résultat : %s | Médiane : %.3f ms\n",
    $contact['courriel'],
    $mediane
);
Résultat attendu
Contacts : 20000 | Résultat : [email protected] | Médiane : [durée variable selon la machine] ms

La durée affichée varie selon le processeur, la version de PHP et le pilote PDO installé ; ne cherchez donc pas à obtenir un nombre précis identique à celui d’un autre poste. Enregistrez plutôt votre médiane avec la date, le moteur, le volume et la requête utilisée. Cette valeur constitue votre référence initiale pour comparer des mesures futures réalisées dans les mêmes conditions.

Interpréter sans conclure trop vite

Ce script mesure le temps entre l’exécution de la requête et la récupération de son résultat. Il ne mesure ni la création des données ni le démarrage d’un serveur HTTP ; il ne suffit donc pas à attribuer toute lenteur ressentie à la base de données. Dans le projet, partez de la requête de recherche existante et de la base de test, gardez la même valeur recherchée et le même jeu de données, puis notez séparément ce que vous chronométrez.

Évitez de lancer la mesure pendant une opération concurrente importante et répétez-la plutôt que de retenir un essai exceptionnellement rapide ou lent. La médiane réduit l’influence de ces valeurs atypiques, mais ne remplace pas une observation sur le système cible. Vous disposez maintenant d’un point de départ mesurable ; la prochaine étape sera d’examiner ce que le moteur fait réellement pour exécuter une requête.

À retenir

  • Fixez le volume de données, la requête et la valeur recherchée pour rendre les essais comparables.
  • Utilisez hrtime(true) pour mesurer une durée écoulée et répétez la mesure.
  • Conservez la médiane et le contexte technique comme référence, sans comparer des environnements différents comme s’ils étaient équivalents.
  • Distinguez le temps de la requête de celui du parcours HTTP complet.

Envie d'aller plus loin ?

Les cours Enovatic sont gratuits et le resteront. Si vous cherchez un accompagnement encadré, nos formations professionnelles sont animées par les mêmes formateurs.