The cost table: pick a structure by what it costs
A data structure is a trade-off: it makes some operations cheap by making others expensive. Big-O describes how the work grows as the input grows. O(1) means "the same work no matter how big", O(n) means "work grows in step with the size", and O(log n) means "doubling the input adds one step". In PHP the question is usually not which class to use but which array function: isset($map[$key]) is O(1), while in_array($value, $list) reads every element.
| Operation | Cost | Why |
|---|---|---|
$a[$key], isset($a[$key]), array_key_exists | O(1) average | hash lookup |
$a[] = $x, array_push, array_pop | O(1) amortised | works at the end, nothing moves |
array_shift, array_unshift | O(n) | every integer key is renumbered |
in_array, array_search | O(n) | scans values one by one |
unset($a[$key]) | O(1) | removes one bucket, leaves a gap in the keys |
sort, usort, ksort | O(n log n) | hybrid insertion sort + quicksort, stable since PHP 8.0 |
array_merge, array_slice, array_values | O(n) | builds a new array |
SplStack push/pop, SplQueue enqueue/dequeue | O(1) | doubly linked list |
SplMinHeap insert/extract, SplPriorityQueue | O(log n) | binary heap |
<?php
$data = range(0, 999_999);
$target = 999_999;
$linearSteps = 0;
foreach ($data as $x) {
$linearSteps++;
if ($x === $target) break;
}
$binarySteps = 0;
$lo = 0;
$hi = count($data) - 1;
while ($lo <= $hi) {
$binarySteps++;
$mid = intdiv($lo + $hi, 2);
if ($data[$mid] === $target) break;
if ($data[$mid] < $target) $lo = $mid + 1;
else $hi = $mid - 1;
}
echo "Linear search: $linearSteps steps\n";
echo "Binary search: $binarySteps steps\n";Linear search: 1000000 steps
Binary search: 20 stepsThe same question, "where is 999,999?", answered by an O(n) and an O(log n) algorithm over one million sorted numbers.
Change $target to 0. Linear search now wins. Why does Big-O still call binary search the better algorithm?
