# PmaControl 5.4.37 contre 5.4.23 — benchmark contrôlé

- Avant : tag `v5.4.23`, commit `b9affcc8601eca978f28c640e62e305d487b6ef0`, Alerting 1.0.6.
- Après : tag `v5.4.37`, commit `d899eef4aad5e50e1297c66c130af5e85de28394`, Alerting 1.0.32.
- Environnement : VM Ubuntu 24.04.4 (2 vCPU, 4 Gio), PHP CLI 8.4.26, MariaDB 10.11.14 locale ; même VM et même schéma de test isolé pour les deux versions.
- Charge : observation `mysql_processlist` synthétique de 53 lignes ; 53 attentes de verrou dans les cas d'incident (18 672 octets JSON), 53 lignes saines ou une liste vide selon le cas. Les mêmes données sont utilisées sur les deux révisions.
- Méthode : horloge `hrtime`, 5 essais par passage, ordre 5.4.23 → 5.4.37 puis ordre inverse ; troisième passage pour le callback sain. Une seule invocation PHP par version/passage ; la base de test est remise en état hors mesure. Les contrôles vérifient l'admission, l'ouverture et la résolution. `N` est le nombre de mesures par version.
- Unités : tous les temps sont en **ms par traitement**. Chaque cellule version indique **moyenne / médiane / p95 / maximum**. La moyenne porte sur les moyennes des essais de même taille ; médiane et p95 sont les médianes des valeurs par essai, et maximum est le maximum observé. `Δ` compare les médianes ; positif signifie plus lent.

## Réservation atomique en MariaDB

| Traitement | N | 5.4.23 : moy./méd./p95/max (ms) | 5.4.37 : moy./méd./p95/max (ms) | Δ médiane | SQL 23 → 37 |
|---|---:|---:|---:|---:|---:|
| Créneau non écoulé | 20000 | 0.1084 / 0.1045 / 0.1427 / 1.672 | 0.1117 / 0.1102 / 0.1446 / 1.354 | +5.5% | 1 → 1 |
| Créneau écoulé | 10000 | 0.5284 / 0.4710 / 0.6582 / 57.562 | 0.5285 / 0.4914 / 0.6686 / 151.669 | +4.3% | 1 → 1 |

## Callback Alerting complet, observation saine

| Traitement | N | 5.4.23 : moy./méd./p95/max (ms) | 5.4.37 : moy./méd./p95/max (ms) | Δ médiane | SQL 23 → 37 |
|---|---:|---:|---:|---:|---:|
| Callback dû | 750 | 2.577 / 2.026 / 2.370 / 61.054 | 6.150 / 5.027 / 6.044 / 239.671 | +148.2% | 7–9 → 23–29 |
| Callback dans le créneau | 750 | 0.3306 / 0.2965 / 0.3617 / 2.485 | 3.231 / 2.952 / 3.378 / 11.724 | +895.8% | 2 → 17 |

## Callback Alerting complet, 53 attentes de verrou

| Traitement | N | 5.4.23 : moy./méd./p95/max (ms) | 5.4.37 : moy./méd./p95/max (ms) | Δ médiane | SQL 23 → 37 |
|---|---:|---:|---:|---:|---:|
| Ouverture d'incident | 200 | 4.605 / 3.956 / 4.502 / 40.843 | 9.519 / 9.044 / 10.977 / 23.217 | +128.6% | 9–11 → 37–39 |
| Rafraîchissement d'incident | 200 | 4.309 / 4.010 / 4.417 / 59.900 | 8.343 / 8.391 / 9.115 / 14.258 | +109.2% | 9 → 35 |
| Résolution d'incident | 200 | 3.638 / 3.047 / 3.547 / 45.572 | 7.755 / 7.132 / 8.484 / 59.717 | +134.1% | 8 → 37 |
| Dispatch listener et rafraîchissement | 200 | 7.766 / 3.960 / 4.825 / 218.401 | 11.046 / 7.683 / 9.253 / 282.259 | +94.0% | 9 → 35 |

## Étapes internes sans base

| Traitement | N | 5.4.23 : moy./méd./p95/max (ms) | 5.4.37 : moy./méd./p95/max (ms) | Δ médiane | SQL 23 → 37 |
|---|---:|---:|---:|---:|---:|
| Décodage JSON, 53 lignes | 20000 | 0.0808 / 0.0708 / 0.1100 / 0.1916 | 0.0866 / 0.0720 / 0.1342 / 0.2083 | +1.6% | 0 → 0 |
| Détection, tri et bornage, 53 attentes | 20000 | 0.2433 / 0.2219 / 0.3444 / 0.6036 | 0.2674 / 0.2342 / 0.4224 / 0.6952 | +5.6% | 0 → 0 |
| Callback sain | 5000 | 0.0528 / 0.0416 / 0.0633 / 0.1436 | 0.0414 / 0.0386 / 0.0513 / 0.1294 | -7.2% | 0 → 0 |
| Ouverture d'incident | 5000 | 0.2466 / 0.2293 / 0.3163 / 0.5163 | 0.2495 / 0.2208 / 0.3422 / 0.7151 | -3.7% | 0 → 0 |
| Rafraîchissement d'incident | 5000 | 0.2573 / 0.2324 / 0.4117 / 0.4910 | 0.2414 / 0.2196 / 0.2986 / 0.4877 | -5.5% | 0 → 0 |
| Résolution d'incident | 5000 | 0.0488 / 0.0412 / 0.0579 / 0.1070 | 0.0556 / 0.0431 / 0.0812 / 0.1953 | +4.6% | 0 → 0 |

## Lecture des résultats et limites

- Le chemin Alerting complet coûte davantage dans 5.4.37 : le callback sain dû passe de 2.026 à 5.027 ms de médiane (+148.2 %) et 7–9 à 23–29 requêtes SQL ; le callback sain dans le créneau passe de 0.297 à 2.952 ms (+895.8 %) et 2 à 17 requêtes. La version récente évalue aussi `QueryMonitorLongRunning` et enregistre l'historique de niveau. Cette comparaison mesure le coût de fonctionnalités ajoutées sur la même entrée.
- Les ouvertures, rafraîchissements, résolutions et dispatchs augmentent aussi en coût. Les 53 attentes déclenchent également la nouvelle règle de requête longue dans 5.4.37 ; les requêtes SQL supplémentaires sont donc attendues et mesurées. Les variations de maximum indiquent des pauses ponctuelles du système de test.
- Le détecteur et la porte de cadence ont le même code source sur les deux révisions ; leurs petits écarts de temps ne démontrent pas un gain ou une régression de l'algorithme. Les mesures internes évitent la base mais ne représentent pas le coût complet du listener.
- Les chiffres historiques affichés pour 5.4.23 provenaient de PHP 8.5.9 et MariaDB 10.11.18 sur un autre environnement. Ils restent archivés et ne servent pas de base directe à ces pourcentages. Aspirateur et Integrate ne sont pas exercés par ce banc ciblé ; aucun delta global de collecte, de débit concurrent ou de durabilité n'en découle.

## Reproduction et données brutes

1. Sur Ubuntu 24.04 avec PHP CLI `mysqli` et MariaDB 10.11, créer la base jetable `pmc_release_bench_20260928`, importer `schema-no-data.sql.zst`, puis `fixture.sql.txt`.
2. Extraire les chemins `App/Library/Alerting`, `App/Library/Listener`, `App/Library/PluginSlot.php` et `plugins/extracted/alerting-*` des tags `v5.4.23` et `v5.4.37` dans deux répertoires `old` et `new`. Le script interne n'a besoin que des classes Alerting.
3. Copier chaque script `.php.txt` en `.php` sur la VM, puis lancer `php benchmark-gate.php old alerting-1.0.6 v5.4.23` et la même commande pour `new alerting-1.0.32 v5.4.37`. Répéter avec `benchmark-alerting-db.php`, `benchmark-alerting-db-incidents.php` et `benchmark-alerting.php`, dans les deux ordres. Les scripts émettent du JSON par passage.
4. `summarize.py.txt` agrège les fichiers JSON de `raw/` en `comparison.json` ; `render_report.py.txt` reproduit ce rapport. Les répertoires de benchmark et la base jetable peuvent ensuite être supprimés.

Données et scripts : [comparaison JSON](comparison.json), [résultat new-db](raw/new-db.json), [résultat new-db2](raw/new-db2.json), [résultat new-db3](raw/new-db3.json), [résultat new-gate](raw/new-gate.json), [résultat new-gate2](raw/new-gate2.json), [résultat new-incidents](raw/new-incidents.json), [résultat new-incidents2](raw/new-incidents2.json), [résultat new](raw/new.json), [résultat new2](raw/new2.json), [résultat old-db](raw/old-db.json), [résultat old-db2](raw/old-db2.json), [résultat old-db3](raw/old-db3.json), [résultat old-gate](raw/old-gate.json), [résultat old-gate2](raw/old-gate2.json), [résultat old-incidents](raw/old-incidents.json), [résultat old-incidents2](raw/old-incidents2.json), [résultat old](raw/old.json), [résultat old2](raw/old2.json), [schéma SQL compressé](schema-no-data.sql.zst), [fixture](fixture.sql.txt), [script de cadence](benchmark-gate.php.txt), [script de callback sain](benchmark-alerting-db.php.txt), [script d'incidents](benchmark-alerting-db-incidents.php.txt), [script interne](benchmark-alerting.php.txt), [agrégation](summarize.py.txt), [génération du rapport](render_report.py.txt).
