Rendering thresholds must be measured in a real browser, apart from the test series that guard behaviour. A separate Vitest project runs scripts/banc/**/*.banc.js in headless Chromium at 1366 x 700, scale 1, without frame-rate limit, CPU throttling set per run; the statistics module gives medians and spreads over repeated samples. Outputs go to an ignored folder. make banc and npm run banc name the entry; its orchestrator comes with the bench measures. Checked: red first; 3410 node tests green from the index; the bench project runs its harness. --- FR --- [ADD] banc : harnais Chromium sans tête, statistiques, entrée make banc Les seuils de rendu se mesurent dans un vrai navigateur, à part des séries qui gardent le comportement. Un projet Vitest distinct joue scripts/banc/**/*.banc.js dans Chromium sans tête à 1366 × 700, facteur 1, sans limite d'images, le ralentissement du processeur réglé par lancement ; le module de statistiques rend médianes et dispersions sur des mesures répétées. Les sorties vont dans un dossier ignoré. make banc et npm run banc nomment l'entrée ; son orchestrateur vient avec les mesures du banc. Vérifié : rouge d'abord ; 3410 node verts depuis l'index ; le projet du banc joue son harnais. Assisted-by: Claude Opus 5.5
37 lines
1.9 KiB
JavaScript
37 lines
1.9 KiB
JavaScript
// © 2026 TechnoLibre (http://www.technolibre.ca)
|
||
// License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
||
|
||
// Les statistiques du temps par image (§ 19.10) : une liste d'intervalles
|
||
// entre images, en millisecondes, rend son nombre, sa médiane, son p95 et
|
||
// son maximum. Module pur, sans import : il se charge sous node comme dans la
|
||
// page du banc, où mesurerImages (navigateur.js) relève les intervalles.
|
||
//
|
||
// Le p95 est celui du rang le plus proche : l'intervalle de rang ⌈0,95 n⌉
|
||
// dans la liste croissante, un intervalle mesuré et non une interpolation
|
||
// entre deux.
|
||
|
||
/**
|
||
* @param {number[]} intervallesMs au moins un ; chacun un nombre fini ≥ 0
|
||
* @returns {{images: number, medianeMs: number, p95Ms: number, maxMs: number}}
|
||
* images : le nombre d'intervalles, une image chacun ; medianeMs : celui du
|
||
* milieu de la liste triée, ou la moyenne des deux du milieu pour une
|
||
* longueur paire. La liste reçue n'est pas modifiée.
|
||
* @throws {TypeError} sur autre chose qu'une liste
|
||
* @throws {RangeError} sur une liste vide, ou un intervalle qui n'est pas un
|
||
* nombre fini positif ou nul, nommé
|
||
*/
|
||
export function statistiques(intervallesMs) {
|
||
if (!Array.isArray(intervallesMs)) throw new TypeError('statistiques : une liste d’intervalles est attendue');
|
||
if (intervallesMs.length === 0) throw new RangeError('statistiques : aucun intervalle');
|
||
for (const valeur of intervallesMs) {
|
||
if (typeof valeur !== 'number' || !Number.isFinite(valeur) || valeur < 0) {
|
||
throw new RangeError(`statistiques : intervalle refusé, ${String(valeur)}`);
|
||
}
|
||
}
|
||
const triees = [...intervallesMs].sort((a, b) => a - b);
|
||
const n = triees.length;
|
||
const milieu = Math.floor(n / 2);
|
||
const medianeMs = n % 2 === 1 ? triees[milieu] : (triees[milieu - 1] + triees[milieu]) / 2;
|
||
const rang95 = Math.ceil((95 * n) / 100);
|
||
return { images: n, medianeMs, p95Ms: triees[rang95 - 1], maxMs: triees[n - 1] };
|
||
}
|