Paste a function or a snippet and the calculator reports its time complexity and space complexity, then shows its work: a numbered derivation of every loop, call, and recursive branch, a loop map annotating each line with its multiplier (×n, ×log n), and an explicit list of every assumption the analysis had to make. Everything runs locally in your browser — the code you paste never leaves the page.
How the analysis works
The engine parses your JavaScript into an AST and walks it composing cost terms. Sequential statements combine as the dominant term of the sum; if/else arms cost the maximum of the branches, because only one runs. Loops multiply: a loop whose variable steps by a constant contributes ×n, and a loop whose variable doubles or halves (i *= 2, i /= 2, i >>= 1) contributes ×log n. Recursion goes through the Master theorem — T(n) = a·T(n/b) + f(n) — with a counted along real execution paths, so a binary search that recurses into one side is correctly treated as a single call per level, while naive Fibonacci branching into two calls is reported as O(2ⁿ).
Built-in operations carry a worst-case cost table: .map(), .filter(), .forEach() are O(n), .sort() is O(n log n), Map.has() is O(1), .includes() and .indexOf() are O(n), .push() is O(1). Calls the engine cannot see are not guessed silently — they are assumed O(1) and disclosed in the assumptions list, so you always know which parts of the answer are measured and which are hypotheses.
What the steps and assumptions mean
The step-by-step panel is the derivation: every line explains one rule that fired, in the order the analysis composed the final term. The loop map lists each loop with its line number and its contribution, which is the fastest way to spot the line that turns an O(n) pass into an O(n²) one. The assumptions panel is the honesty layer: loop bounds are treated as the input size n (the standard convention), early returns inside loops report the worst case, and unknown functions are called out as assumed O(1). Exact asymptotic analysis is undecidable in general — any tool that never admits that is hiding guesses, and this one prefers to show them.
Comparing two versions
The Compare tab analyzes two snippets side by side and states the verdict at a working size you choose: at n = 1,000, an O(n) pass does about a thousand operations while an O(n²) pair loop does a million — roughly 1,000× the work. This is the classic interview refactor in miniature: paste the brute-force two-sum with its nested loops next to the hash-map version and watch the ratio. When both sides land in the same growth class, the verdict says so — constants decide then, and asymptotics cannot.
Growth curves and the one-second budget
The Growth tab plots operation counts for the standard classes — O(1), O(log n), O(n), O(n log n), O(n²), O(n³), O(2ⁿ), O(n!) — on a log scale where every class becomes a readable curve (exponential and factorial families only fit on the log scale, which is exactly the point). The table below the chart counts operations at n from 10 to a million and shows the largest n each class can finish within one second, assuming roughly 10⁸ simple operations per second. A quadratic algorithm exhausts that budget at n ≈ 10,000; a linear one reaches a hundred million. Those cutoffs, more than any formula, are what “faster” means in practice.
Frequently asked questions
Which languages does the analyzer understand? JavaScript (including modern syntax). The analysis itself is shape-based — loops, recursion, and call structure — so the same reasoning transfers to Java, Python, or C++ snippets of similar shape, but only JavaScript is parsed directly.
Can it be wrong? It is a heuristic analyzer, and it says so. Data-dependent bounds, memoization, and clever invariants are beyond static analysis in general; in those cases the tool reports the worst case it can defend and lists the assumption it made. For the canonical educational patterns — scans, nested loops, binary search, merge sort, dynamic-programming loops — the classification matches the textbook.
What is space complexity based on? Allocations whose size depends on n (arrays, .slice(), Map/Set), values accumulated across loop iterations, and recursion depth. A matrix built row by row inside a loop is O(n²); a merge sort’s auxiliary arrays make it O(n) space.
Is my code sent anywhere? No. Parsing, analysis, charting, and the comparison all run in your browser; there is no backend call, no logging of your code, and nothing stored beyond your last inputs in your own browser’s local storage.