Reasoning about complexity from source code is guesswork the moment a library call is involved. The Big-O Analyzer takes the other route: it runs your function at a series of input sizes, times each one, and fits the measured growth against 9 candidate curves. What comes back is an observation rather than an opinion.
Two design decisions make the numbers worth reading. Input construction is a separate untimed step, so an O(n) generator does not contaminate the measurement of an O(log n) algorithm. And each size is run enough times to fill a sampling budget, defaulting to 60 milliseconds, so a fast function is measured across many repetitions rather than once against clock noise.
Everything executes in a Web Worker, which keeps the page responsive and lets a hung run be killed instead of freezing the tab. Your code is never uploaded; it is compiled into a worker on your own machine.
Getting a Reliable Measurement
- Start from a preset. Linear scan, Built-in sort, Nested loop over pairs, Sieve of Eratosthenes and Subset enumeration between them span O(n) to O(2ⁿ), and each arrives with sizes already tuned to its shape.
- Put data construction in the setup pane and the thing you are measuring in the algorithm pane. Getting this split wrong is the single most common reason a result looks nonsensical.
- Choose input sizes that at least double, ideally 4 or 5 of them. The fit needs a minimum of 3 usable rows, and up to 12 sizes are accepted.
- Run it and watch the ratio column. A doubling of n that quadruples the time is O(n²) and no curve fitting is needed to see it.
- Read the best fit with its error percentage and the measured growth exponent with its R². Two independent statements agreeing is what makes a verdict trustworthy.
Accuracy and What Distorts a Timing
- Anything under 1 millisecond per run is flagged as unreliable, and a measurement near the 0.02 millisecond noise floor is essentially timer resolution. Raise the input sizes rather than trusting it.
- JIT warm-up distorts the first size measured. That is exactly why several sizes are used and the fit ignores any row that failed to clear the reliability bar.
- Garbage collection can add a spike to a single size and pull a fit towards the wrong curve. Rerun before believing an odd result, since the pause will land somewhere else.
- Cache effects produce a genuine bend in the curve that no complexity class predicts. An algorithm can measure superlinear purely because the data stopped fitting in L2.
- Each size is capped at 2,500 milliseconds and a hung run is killed after a further 4 seconds of slack, so an accidental infinite loop costs you a few seconds rather than the tab.
- Input sizes are capped at 50,000,000, which is a memory bound rather than a time bound. Building an array that large in the setup step is what will fail first.
How It Calculates the Verdict
- Each of the 9 candidate curves is scaled to your measurements and scored by relative error. The lowest error wins and its percentage is shown, so a poor fit is visible as a poor fit.
- A separate least-squares line is fitted through the log of n against the log of time. Its slope is the growth exponent directly: 1.0 is linear, 2.0 is quadratic, and R² says how straight the line was.
- The doubling column beside each candidate is the theoretical ratio. O(n log n) is roughly 2.1 times per doubling against O(n) at exactly 2.0, which is why the two need several sizes to separate.
- Extrapolation projects the fitted curve out to a target size, 200,000 by default, and bands it against a time limit of 2 seconds as safe under half the limit, tight up to the limit, and TLE risk beyond it.
- An extrapolation is only as good as the fit behind it. Projecting an O(2ⁿ) curve a long way out produces a number so large it is reported as a duration rather than a figure, which is the correct amount of precision for it.