← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Amortized Analysis

Algorithms Advanced
debt(d7/e3/b3/t6)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). The detection_hints explicitly state automated detection is 'no'. Misapplying amortized analysis (e.g., claiming O(1) when it's O(n), or using amortized-O(1) structures in real-time paths) cannot be caught by linters, SAST tools, or compilers. It requires careful code review or runtime profiling/benchmarking to identify the mismatch between claimed and actual complexity behavior.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix indicates measuring average cost over N operations and choosing the right data structure. Fixing a misuse typically means swapping one data structure for another (e.g., replacing array_shift with SplQueue, or switching from a dynamic array to a pre-allocated one in real-time code). This is a localized fix touching a few call sites, not an architectural rework.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). This is a conceptual/analytical tool that applies to specific data structure choices rather than pervading the entire codebase. The applies_to contexts (web, cli) are broad, but the actual impact of understanding amortized analysis is localized to performance-critical sections. It doesn't shape the system's architecture — it informs specific implementation choices in isolated components.

t6 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap' (t5), +1 to t6. The misconception is clear and significant: developers frequently assume amortized O(1) means every operation is O(1). This is a well-documented gotcha that most developers eventually learn, but it contradicts the intuitive reading of 'O(1)' and causes real problems in latency-sensitive code. The additional common mistakes (not knowing array_shift is O(n), assuming SplStack vs array equivalence) compound the confusion. Slightly worse than a standard t5 because the 'O(1)' label actively misleads — it looks like a worst-case guarantee to anyone who hasn't specifically studied amortized analysis.

About DEBT scoring →

Also Known As

amortized O(1) amortized cost potential method aggregate analysis

TL;DR

Averaging the cost of an operation over a sequence — explaining why dynamic array append is O(1) amortised despite occasional O(n) resizes.

Explanation

Some operations are occasionally expensive but rarely so. Amortized analysis spreads the cost: a dynamic array doubles capacity when full — a resize is O(n) but happens so rarely that over n appends the average is O(1). The accounting method assigns 'credits' from cheap operations to pay for future expensive ones. PHP's array[] = $item is amortized O(1) for the same reason. Amortized != average: average considers random inputs; amortized considers worst-case sequences. The difference matters when budgeting for occasional spikes.

Common Misconception

Amortized O(1) means every operation is O(1) — amortized O(1) means the average over a sequence is O(1); individual operations can still spike to O(n), which matters for real-time systems.

Why It Matters

Understanding amortized analysis explains why PHP's array_push is fast despite occasional internal reallocation, and why you must not rely on O(1) amortized in real-time code that cannot tolerate spikes.

Common Mistakes

  • Confusing amortized O(1) with worst-case O(1) — occasional spikes still happen.
  • Using dynamic arrays in hard real-time systems — the O(n) resize spike causes deadline misses.
  • Not understanding that PHP unshift/shift are O(n) NOT O(1) amortized — they reindex every time.
  • Assuming stack operations are always cheap — SplStack push/pop are O(1) amortized, but array_shift is O(n).

Avoid When

  • Do not use amortized O(1) as a guarantee for real-time or latency-sensitive systems — the occasional O(n) resize still happens.
  • Avoid citing amortized cost when your workload triggers worst-case operations systematically (e.g. always inserting at max-load).

When To Use

  • When evaluating data structures whose worst-case single operation cost is misleading (dynamic arrays, hash table rehashing, splay trees).
  • When choosing between two structures with similar average performance — amortized cost reveals the true cost per operation over a sequence.
  • When documenting API complexity guarantees to callers who care about throughput rather than single-call latency.

Code Examples

💡 Note
The bad example assumes array append is always fast in a 16 ms real-time budget; the fix uses a pre-allocated structure to avoid unpredictable resize pauses in a timing-critical loop.
✗ Vulnerable
// Mistaking amortized for guaranteed:
function realtimeTask(SplDoublyLinkedList $queue): void {
    // In a 16ms real-time frame:
    $queue->push($data); // Usually O(1)... but occasionally O(n) on resize
    // Frame budget exceeded! Dropped frame in a game/audio context
}
✓ Fixed
// Understand what 'amortized O(1)' means:
// For N total pushes to a dynamic array:
// - ~N pushes are O(1)
// - log(N) resizes are O(N) each
// Total: O(N) for N operations = O(1) amortized

// Pre-allocate to avoid all resize overhead:
$spl = new SplFixedArray(10000); // O(1) guaranteed access, no resize
for ($i = 0; $i < 10000; $i++) {
    $spl[$i] = $data[$i]; // Always O(1) — no resize possible
}

Added 16 Mar 2026
Edited 31 Mar 2026
Views 54
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 2 pings F 1 ping S 0 pings S 0 pings M 1 ping T 2 pings W 1 ping T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Amazonbot 10 Google 6 Perplexity 5 Ahrefs 4 SEMrush 4 Unknown AI 3 Bing 2 Claude 2 ChatGPT 2 Scrapy 2 Meta AI 1 PetalBot 1
crawler 37 crawler_json 4 pre-tracking 1
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Medium
⚡ Quick Fix
When a single operation is occasionally expensive but rarely so, measure the average cost per operation over N operations — PHP's array reallocation is O(n) occasionally but O(1) amortised
📦 Applies To
any web cli
🔗 Prerequisites
🔍 Detection Hints
Worst-case analysis of PHP array append showing O(n) when amortised cost is O(1); incorrect complexity claims for dynamic arrays
Auto-detectable: ✗ No
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: High Context: Function


✓ schema.org compliant