Learn the concept
Algorithmic complexity describes how work grows with input size. A nested comparison of every pair grows differently from one pass using a lookup. Practical performance also depends on constants, input shape, I/O, and memory allocation.
Measure before optimizing. Use a representative input and compare outputs as well as execution time. A faster implementation that changes duplicate handling is a behavior change, not merely an optimization. Separate CPU time from time spent waiting on dependencies.
Avoid repeatedly copying a growing list or concatenating large immutable strings in a loop when a collection-and-join approach is appropriate. Streaming reduces peak memory only if later stages also preserve incremental processing. Sorting the entire stream still requires collecting data.
Run and inspect
def unique_in_order(items):
seen = set()
output = []
for item in items:
if item not in seen:
seen.add(item)
output.append(item)
return output
assert unique_in_order(["b", "a", "b"]) == ["b", "a"]
Your exercise
Compare list-membership deduplication with set-backed deduplication on increasing input sizes. Preserve the order of first occurrence.
Check your understanding
The results match and the report explains expected growth without claiming a universal timing from one machine.