Choosing the Right Data Structure Is a Design Decision

Data structure selection is often taught as a performance question. In practice, it's a clarity question — and clarity compounds.

The textbook framing of data structures centres on time complexity. Arrays give you O(1) access, linked lists give you O(1) insertion, hash maps give you O(1) average-case lookup. Pick the one with the best Big-O for your access pattern.

This framing is correct but incomplete. In most production systems, the dominant concern isn’t raw performance — it’s comprehensibility. The right data structure makes the code’s intent legible. The wrong one obscures it, even if the asymptotic complexity is identical.

An example

Consider a system that processes trade events. Each event has a timestamp and a symbol. You need to track the most recent event per symbol.

A list of tuples works. So does a dictionary keyed by symbol. Both support the required operations. But the dictionary communicates intent: “there is one canonical event per symbol, and we access it by symbol.” The list communicates nothing — it requires the reader to infer the invariant by reading the surrounding code.

# Unclear intent
events = []
for e in stream:
    events = [x for x in events if x.symbol != e.symbol]
    events.append(e)

# Clear intent
latest = {}
for e in stream:
    latest[e.symbol] = e

The second version is faster, yes. But more importantly, it’s harder to misuse. A new engineer reading this code immediately understands the constraint.

Why this matters at scale

In small scripts, data structure choice is a minor aesthetic preference. In systems with hundreds of contributors and multi-year lifespans, it compounds. Every unclear structure becomes a source of bugs, misunderstandings, and defensive code that exists only to compensate for earlier ambiguity.

The best engineers I’ve worked with choose data structures for their communicative properties first. Performance matters, but it’s rarely the binding constraint — and when it is, the profiler will tell you. Clarity has no profiler. You either design for it upfront or you pay for its absence indefinitely.