{
    "slug": "amortized_analysis",
    "term": "Amortized Analysis",
    "category": "algorithms",
    "difficulty": "advanced",
    "short": "Averaging the cost of an operation over a sequence — explaining why dynamic array append is O(1) amortised despite occasional O(n) resizes.",
    "long": "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.",
    "aliases": [
        "amortized O(1)",
        "amortized cost",
        "potential method",
        "aggregate analysis"
    ],
    "tags": [
        "algorithms",
        "performance",
        "complexity"
    ],
    "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)."
    ],
    "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."
    ],
    "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)."
    ],
    "related": [
        "big_o_notation",
        "dynamic_programming",
        "heap_data_structure",
        "array_data_structure"
    ],
    "prerequisites": [
        "big_o_notation",
        "dynamic_programming",
        "hash_table"
    ],
    "refs": [
        "https://en.wikipedia.org/wiki/Amortized_analysis"
    ],
    "bad_code": "// Mistaking amortized for guaranteed:\nfunction realtimeTask(SplDoublyLinkedList $queue): void {\n    // In a 16ms real-time frame:\n    $queue->push($data); // Usually O(1)... but occasionally O(n) on resize\n    // Frame budget exceeded! Dropped frame in a game/audio context\n}",
    "good_code": "// Understand what 'amortized O(1)' means:\n// For N total pushes to a dynamic array:\n// - ~N pushes are O(1)\n// - log(N) resizes are O(N) each\n// Total: O(N) for N operations = O(1) amortized\n\n// Pre-allocate to avoid all resize overhead:\n$spl = new SplFixedArray(10000); // O(1) guaranteed access, no resize\nfor ($i = 0; $i < 10000; $i++) {\n    $spl[$i] = $data[$i]; // Always O(1) — no resize possible\n}",
    "example_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.",
    "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",
    "severity": "low",
    "effort": "medium",
    "created": "2026-03-16",
    "updated": "2026-03-31",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/amortized_analysis",
        "html_url": "https://codeclaritylab.com/glossary/amortized_analysis",
        "json_url": "https://codeclaritylab.com/glossary/amortized_analysis.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Amortized Analysis](https://codeclaritylab.com/glossary/amortized_analysis) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/amortized_analysis"
            }
        }
    }
}