Collez une fonction ou un extrait et le calculateur affiche sa complexité en temps et sa complexité en espace, puis montre son raisonnement : une dérivation numérotée de chaque boucle, appel et branche récursive, une carte des boucles annotant chaque ligne de son multiplicateur (×n, ×log n), et une liste explicite de chaque hypothèse que l’analyse a dû faire. Tout s’exécute localement dans votre navigateur — le code que vous collez ne quitte jamais la page.
Comment fonctionne l’analyse
Le moteur analyse votre JavaScript en AST puis le parcourt en composant des termes de coût. Les instructions séquentielles se combinent en terme dominant de la somme ; les branches if/else coûtent le maximum des deux bras, puisqu’une seule s’exécute. Les boucles multiplient : une boucle dont la variable progresse d’une constante contribue ×n, et une boucle dont la variable double ou diminue de moitié (i *= 2, i /= 2, i >>= 1) contribue ×log n. La récursion passe par le théorème maître — T(n) = a·T(n/b) + f(n) — avec a compté le long des chemins d’exécution réels : une recherche dichotomique qui ne rappelle que d’un côté est correctement traitée comme un seul appel par niveau, tandis qu’un Fibonacci naïf qui se divise en deux appels est rapporté en O(2ⁿ).
Les opérations intégrées disposent d’une table des coûts au pire cas : .map(), .filter(), .forEach() sont en O(n), .sort() en O(n log n), Map.has() en O(1), .includes() et .indexOf() en O(n), .push() en O(1). Les appels que le moteur ne peut pas voir ne sont pas devinés en silence — ils sont supposés O(1) et signalés dans la liste des hypothèses, pour que vous sachiez toujours quelles parties de la réponse sont mesurées et lesquelles sont des suppositions.
Ce que signifient les étapes et les hypothèses
Le panneau étape par étape est la dérivation : chaque ligne explique une règle qui s’est déclenchée, dans l’ordre où l’analyse a composé le terme final. La carte des boucles liste chaque boucle avec son numéro de ligne et sa contribution — le moyen le plus rapide de repérer la ligne qui transforme un parcours en O(n) en O(n²). Le panneau hypothèses est la couche d’honnêteté : les bornes de boucles sont traitées comme la taille d’entrée n (la convention standard), les return précoces dans les boucles rapportent le pire cas, et les fonctions inconnues sont signalées comme supposées O(1). L’analyse asymptotique exacte est indécidable en général — tout outil qui ne l’admet jamais cache ses devinettes, et celui-ci préfère les montrer.
Comparer deux versions
L’onglet Comparer analyse deux extraits côte à côte et énonce le verdict à une taille de travail que vous choisissez : à n = 1 000, un parcours en O(n) fait environ mille opérations là où une double boucle en O(n²) en fait un million — environ 1 000× le travail. C’est le refactor d’entretien classique en miniature : collez le two-sum en force brute avec ses boucles imbriquées à côté de la version par table de hachage et observez le rapport. Quand les deux côtés tombent dans la même classe de croissance, le verdict le dit — ce sont alors les constantes qui décident, et l’asymptotique ne le peut pas.
Courbes de croissance et budget d’une seconde
L’onglet Croissance trace les nombres d’opérations des classes standard — O(1), O(log n), O(n), O(n log n), O(n²), O(n³), O(2ⁿ), O(n!) — sur une échelle log où chaque classe devient une courbe lisible (les familles exponentielle et factorielle ne tiennent que sur l’échelle log, c’est précisément le propos). Le tableau sous le graphique compte les opérations pour n de 10 à un million et montre le plus grand n que chaque classe peut terminer en une seconde, en supposant environ 10⁸ opérations simples par seconde. Un algorithme quadratique épuise ce budget à n ≈ 10 000 ; un linéaire atteint cent millions. Ces seuils, plus que toute formule, sont ce que « plus rapide » veut dire en pratique.
Questions fréquentes
Quelles langues l’analyseur comprend-il ? JavaScript (syntaxe moderne incluse). L’analyse elle-même repose sur la forme — boucles, récursion, structure des appels — donc le même raisonnement se transpose à des extraits Java, Python ou C++ de forme similaire, mais seul JavaScript est analysé directement.
Peut-il se tromper ? C’est un analyseur heuristique, et il le dit. Les bornes dépendantes des données, la mémoïsation et les invariants astucieux dépassent l’analyse statique en général ; dans ces cas, l’outil rapporte le pire cas qu’il peut défendre et liste l’hypothèse faite. Pour les motifs éducatifs canoniques — parcours, boucles imbriquées, recherche dichotomique, tri fusion, boucles de programmation dynamique — la classification correspond au manuel.
Sur quoi repose la complexité spatiale ? Les allocations dont la taille dépend de n (tableaux, .slice(), Map/Set), les valeurs accumulées à travers les itérations, et la profondeur de récursion. Une matrice construite ligne par ligne dans une boucle est en O(n²) ; les tableaux auxiliaires d’un tri fusion le mettent en O(n) d’espace.
Mon code est-il envoyé quelque part ? Non. L’analyse, les graphiques et la comparaison s’exécutent dans votre navigateur ; aucun appel réseau, aucune journalisation de votre code, et rien n’est conservé au-delà de vos dernières saisies dans le stockage local de votre propre navigateur.