Maison >interface Web >js tutoriel >ESBench : un outil de benchmarking moderne

ESBench : un outil de benchmarking moderne

Barbara Streisand
Barbara Streisandoriginal
2024-09-25 06:28:06290parcourir

benchmark.js se termine en avril 2024, il est temps qu'une nouvelle génération d'outils émerge !

ESBench est un nouvel outil d'analyse comparative JavaScript publié en 2024. Il est conçu pour fournir une prise en charge d'analyse comparative simple et évolutive pour les projets JS modernes.

Dépôt GitHub

Le problème

  • Au début, JavaScript était exécuté directement à partir des sources, mais à mesure que les applications sont devenues plus complexes, cela est devenu de moins en moins le cas. Les applications modernes doivent souvent être construites, ce qui nécessite des outils d'analyse comparative pour pouvoir intégrer le processus de construction, et l'impact de la construction sur les performances doit être pris en compte.

  • JavaScript n'a pas de « runtime officiel », les navigateurs, Node, Deno et plus récemment Bun, revendiquent tous des performances élevées. Mais qu’en est-il dans votre propre code ? Ce serait cool s'il existait un outil capable d'exécuter des tests de performance dans plusieurs environnements d'exécution et d'exporter les résultats dans un seul rapport —— c'était ma principale motivation pour créer ESBench.

  • Il y a certaines fonctionnalités utiles que je ne pense pas que les outils de référence JS soient capables de faire, comme le calcul de la complexité asymptotique, la validation de la valeur de retour et le tracé des résultats dans un graphique interactif. .

Benchmark avec ESBench

Pour résoudre ces problèmes, j'ai décidé de créer un nouvel outil contenant toutes les fonctionnalités dont j'avais besoin et doté d'une API simple.

Après environ un an de développement, ESBench est né.

Vous pouvez essayer ESBench en ligne

Suite d'écriture

ESBench opte pour des API et des fermetures déclaratives, qui sont la manière la plus populaire d'écrire JS.

Comparez Set.has et Array.includes :

// benchmark/array-vs-set.js
export default scene => {
    const length = 1000;
    const array = Array.from({ length }, (_, i) => i);

    const set = new Set(array);
    const value = array[Math.floor(array.length / 2)];

    scene.bench("Set", () => set.has(value));
    scene.bench("Array", () => array.includes(value));
};

Exécutez pnpm exec esbench pour exécuter la suite, le résultat :

Suite: benchmark/array-vs-set.js
| No. |  Name |      time | time.SD |
| --: | ----: | --------: | ------: |
|   0 |   Set |   3.64 ns | 0.00 ns |
|   1 | Array | 326.36 ns | 0.17 ns |

Un peu plus de fonctionnalités

Le paramétrage et les lignes de base sont des exigences fréquentes, ESBench les prend en charge avec des options simples.

export default {
    baseline: { type: "type", value: Set },
    params: {
        length: [10, 10_000],
        type: [Set, Array],
    },
    setup(scene) {
        const { length, type } = scene.params;

        // Prepare
        const array = Array.from({ length }, (_, i) => i);
        const set = new Set(array);
        const value = array[Math.floor(array.length / 2)];

        // Support conditions
        if (type === Set) {
            // Define benchmark cases
            scene.bench("create", () => new Set(array));
            scene.bench("has", () => set.has(value));
        } else {
            scene.bench("create", () => [...array]);
            scene.bench("has", () => array.includes(value));
        }
    },
};

Le rapport texte :

ESBench: A modern benchmarking tool

Exécution croisée

Retour au problème ci-dessus, qui s'applique à tous les environnements d'exécution :

// esbench.config.js
import { defineConfig, ProcessExecutor, ViteBuilder, WebRemoteExecutor } from "esbench/host";

export default defineConfig({
    toolchains: [{
        // Build your benchmark code with Vite, require vite installed.
        builders: [new ViteBuilder()],
        executors: [
            // Run suite on Node.
            new ProcessExecutor("node"),

            // Run suite on Bun.
            new ProcessExecutor("bun"),

            // Open the default browser to run benchmark,
            // in my computer it's Firefox.
            {
                name: "Firefox",
                use: new WebRemoteExecutor({ open: {} }),
            },
        ],
    }],
});

Vous pouvez également définir un runtime comme référence :

import { defineSuite } from "esbench";

export default defineSuite({
    baseline: { type: "Executor", value: "node" },
    setup(scene) {
        const length = 1000;
        const array = Array.from({ length }, (_, i) => i);

        const set = new Set(array);
        const value = array[Math.floor(array.length / 2)];

        scene.bench("Set", () => set.has(value));
        scene.bench("Array", () => array.includes(value));
    },
});

Le résultat :

| No. |  Name | Executor |      time | time.SD | time.ratio |
| --: | ----: | -------: | --------: | ------: | ---------: |
|   0 |   Set |     node |   3.69 ns | 0.03 ns |   baseline |
|   1 |   Set |      bun |   0.00 ns | 0.00 ns |   -100.00% |
|   2 |   Set |  Firefox |   0.00 ns | 0.00 ns |   -100.00% |
|     |       |          |           |         |            |
|   3 | Array |     node | 325.02 ns | 1.00 ns |   baseline |
|   4 | Array |      bun | 324.87 ns | 0.08 ns |     -0.04% |
|   5 | Array |  Firefox | 516.70 ns | 0.75 ns |    +58.98% |
Warnings:
[No.1] Set: The function duration is indistinguishable from the empty function duration.
[No.2] Set: The function duration is indistinguishable from the empty function duration.

Plus de cas d'utilisation

ESBench peut faire bien plus qu'une utilisation de base :

  • Calculer la complexité temporelle Big-O des fonctions
  • Mesurer le temps de compression/décompression et la taille de sortie des fonctions zlib
  • Valider la valeur de retour avant le benchmark
  • Benchmark sur les 3 images de GitHub Action

Conclusion

Si vous en avez assez d'écrire des benchmarks en JavaScript, ESBench est la bibliothèque que vous attendiez.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn