Stop Guessing Why Your App is Slow: A Pragmatic Guide to Big O Notation
Source: Dev.to
Why Big O Matters
When we start coding, the main goal is often just to make things work. Once a feature ships and bugs are squashed, we’re happy. But as the user base grows and data sets swell, simple operations—like iterating over an array—can freeze the browser.
Big O is a way to talk about how code performance scales as input size grows. It answers the question: If my input gets 10× bigger, how much slower does my app get?
The Space‑Time Tradeoff
Most of the time, making an algorithm faster (better time complexity) requires using more memory (higher space complexity) to store temporary data, such as lookup tables. On devices with limited RAM (e.g., older mobile phones), you might deliberately choose a slower algorithm to avoid out‑of‑memory crashes. Optimization is always about context.
Quadratic vs. Linear: Using a Set
Imagine a Yard Management System (YMS) that tracks truck license plates. You have:
arriving– plates of newly arrived trucksregistered– plates already stored in the database
You need to find which arriving trucks are already registered.
Brute‑force (O(n²))
function findRegisteredTrucks(arriving: string[], registered: string[]): string[] {
const matches: string[] = [];
for (let i = 0; i = {};Optimized with a Set (O(n))
function findRegisteredTrucksOptimized(arriving: string[], registered: string[]): string[] {
const registeredSet = new Set(registered);
return arriving.filter(plate => registeredSet.has(plate));
}Sorting is inherently more complex than simple iteration, but O(n log n) is the optimal standard rate for comparison‑based sorts.
Takeaways
- Mind your loops – avoid nested loops on large data sets.
- Leverage
SetandMapfor O(1) lookups. - Cache results (memoization) when repeated calculations occur.
- Remember the space‑time tradeoff: faster algorithms often need more memory.
What was the worst performance bottleneck you ever fixed? Share your story in the comments! 👇