VoidRuns_
Home/Tools/Code Complexity Analyzer
CODE TOOLS
Static analysis · client-side

Code Complexity Analyzer

Paste your TypeScript, JavaScript, C#, or Python code to detect O(n²) loops, memory leaks, and performance anti-patterns. Client-side only — nothing leaves your browser.

</>

Paste code and click Analyze →

Runs 100% client-side. Nothing is sent to a server.

Big O Complexity and Why It Matters for Real Applications

Big O notation describes how an algorithm's runtime or memory usage grows relative to input size. The difference between O(n) and O(n²) is irrelevant at n=100 and catastrophic at n=100,000. Modern applications routinely operate on datasets where these differences cause 10–1000× performance gaps between a correct and an optimized implementation.

The Most Common Performance Killers

Nested LoopsO(n²)

The classic: for (i) { for (j) { ... } }. At n=1000, that's 1,000,000 operations. At n=10,000 it's 100,000,000. The fix is almost always to convert the inner loop into a Map/Set lookup — converting the inner from O(n) to O(1) and the whole algorithm from O(n²) to O(n).

String Concatenation in LoopsO(n²) memory

result += item creates a new string on every iteration, copying all previous content. At n=10,000 string appends, you've performed 50,000,000 character copies. Fix: collect into an array and call .join('') once (JS/TS) or use StringBuilder (C#/Java).

DOM Queries in LoopsO(n) extra traversals

document.getElementById() and querySelector() traverse the DOM tree on every call. Inside a loop of n iterations, you're traversing the entire DOM n times. Cache the reference outside the loop: const el = document.getElementById('x'); before the loop.

Event Listener LeaksMemory growth

Every addEventListener without a corresponding removeEventListener adds to memory. In React components, this must be cleaned up in useEffect's return function. Accumulated listeners also cause unexpected double-fire behavior when components remount.

C#-Specific Patterns: When LINQ Goes Wrong

LINQ is powerful but deceptively easy to misuse. .Select().Where() instead of .Where().Select() projects every element before filtering — discarding work proportional to the filter rejection rate. Calling .ToList() mid-query materializes and re-iterates. And task.Result is arguably the most dangerous pattern in all of C# — it blocks the thread pool, risks deadlocks in ASP.NET, and defeats the entire purpose of async/await.

Frequently Asked Questions

How does the analyzer detect Big O complexity?+

The analyzer uses static pattern matching: it counts the maximum nesting depth of loops (for, while, forEach) and detects recursive patterns. Triple-nested loops → O(n³), double-nested → O(n²), single → O(n), no loops → O(1). It also flags specific patterns like nested forEach callbacks and LINQ chaining in C#. This is heuristic analysis — it identifies likely complexity class, not a formal proof.

Is my code sent to a server?+

No. All analysis runs entirely in your browser using JavaScript. Your code never leaves your machine. There are no API calls, no logging, no storage. You can verify this by opening DevTools → Network and observing zero requests when you click Analyze.

What languages are supported?+

TypeScript, JavaScript, C#, and Python. Each language has its own pattern set targeting common anti-patterns in that ecosystem: event listener leaks and DOM access in loops for JS/TS, StringBuilder vs string+= for C#, and comprehension complexity for Python. More languages may be added in future updates.

Why does the analyzer flag string += in a loop as a critical issue?+

Strings are immutable in most languages. Each string += creates a new string object by copying all previous content plus the new addition. In a loop of n iterations over average string length m, this creates O(n²) total memory allocations. For small loops this is negligible; for processing thousands of items (log lines, CSV rows, JSON building) it causes serious GC pressure and 10–100× slowdowns vs StringBuilder or Array.join().

The analyzer detected an issue but my code is fine — why?+

Static analysis without execution context produces false positives. The analyzer flags structural patterns that are typically problematic, but your specific usage may be safe: e.g., a 'nested loop' that always runs a fixed small inner count (like iterating RGB channels), or a 'DOM access in loop' where the loop count is bounded to 3–5 elements. Use the issues as a checklist for review, not as a definitive bug list.

What's the difference between the Complexity, Memory, and Overall scores?+

Complexity Score (0–100) measures algorithmic efficiency based on loop nesting depth and recursion. Memory Score measures allocation patterns, potential leaks, and GC pressure. Overall Score combines both with a penalty for critical (-15 pts) and warning (-5 pts) issues. A score above 70 means the code has no obvious performance problems. Below 40 means there are serious issues worth refactoring before shipping.