Counting Operations

RoadmapsDSA

Overview

Counting operations means tallying the number of primitive steps — comparisons, assignments, arithmetic — an algorithm performs as a function of the input size n. It is the concrete measurement that asymptotic notation (Big-O) later abstracts.

Two algorithms that both produce correct output can differ by orders of magnitude in speed. Without counting operations, the only way to discover this is to run them on large inputs and hope you notice. Counting gives you a mathematical function T(n) that predicts performance before the code ever executes.

Where used: Interview prep: estimating whether an O(n^2) solution will pass within a 10^8 operations-per-second budget given constraints, Database query planning: the optimizer counts estimated disk reads and comparisons to choose the fastest execution plan

Why learn this

Aha moment

# Algorithm A: linear scan
def find_max_a(arr):
    best = arr[0]        # 1 assignment
    for x in arr[1:]:    # n-1 iterations
        if x > best:     # 1 comparison each
            best = x     # 0 to n-1 assignments
    return best          # Total: between n and 2n-1 ops

# Algorithm B: sort then pick last
def find_max_b(arr):
    arr.sort()           # roughly n*log(n) comparisons
    return arr[-1]       # 1 access

Prediction: Both find the maximum — but how many operations does each actually do?

Common guess: They are about the same since both look at all elements.

Algorithm A does roughly n comparisons — one per element. Algorithm B sorts the entire array first, doing roughly n*log(n) comparisons plus n*log(n) swaps, only to grab a single element at the end. Counting operations reveals B does vastly more work than needed. The correct answer was already accessible in one pass.

Common mistakes

Glossary

asymptotic notation
A mathematical way to describe how an algorithm's performance changes as input size grows.
primitive steps
The most basic, fundamental actions a computer can perform, like addition or comparison.
orders of magnitude
Significantly larger scale, typically measured in factors of ten (e.g., 10x, 100x, 1000x faster).

Recall questions

Understanding checks

After this code runs for input size n, what is the value of count? Express it as a closed-form formula.

count = n*(n-1)/2. The inner loop runs 0 + 1 + 2 + ... + (n-1) times, which sums to n*(n-1)/2.

This is the classic triangular-sum pattern that appears in algorithms like insertion sort and bubble sort. Recognizing this sum immediately tells you the algorithm is O(n^2).

Two algorithms both solve the same problem: Algorithm A performs 5n + 20 operations and Algorithm B performs 2n^2 + 3 operations. For small n (say n = 3), B is faster. At what point does A become faster, and why does this matter?

Setting 5n + 20 = 2n^2 + 3 and solving gives a crossover around n = 4. Beyond that, A is faster and the gap grows rapidly. This matters because real-world inputs are typically large — what looks faster on toy inputs can be catastrophically slower at scale.

This illustrates why constant factors and lower-order terms matter for small inputs but the highest-degree term dominates at scale — the exact motivation for Big-O abstraction.

Practice tasks

Count the exact operations in a bubble sort pass

The starter code performs one pass of bubble sort on a 5-element array. Add a counter variable that increments on every comparison and every swap. Run it mentally (dry run) and predict the final counter value before checking.

Continue learning

Previous: What is an Algorithm?

Previous: Iteration & Traversal

Next: Big-O Notation

Next: Common Complexities

Return to DSA Roadmap