---
status: pending
priority: p2
issue_id: "006"
tags: [code-review, performance, python]
---

# `statistics.median()` on unbounded list of font-size floats

## Problem Statement

`_detect_from_headings()` collects one float per text span across the entire document into `all_sizes`, then calls `statistics.median()` which requires sorting the full list. A dense 1000-page technical book can produce hundreds of thousands of spans, making this an O(n log n) sort over millions of entries before the first heading is identified.

This runs twice per CLI invocation due to the double-detection bug (see todo 003).

## Findings

**`condensr/parser.py:193-208`:**
```python
all_sizes = []
for page in doc:
    ...
    for span in line["spans"]:
        text = span["text"].strip()
        if text:
            all_sizes.append(span["size"])  # one per span, unbounded

median_size = statistics.median(all_sizes)  # sorts entire list
```

Font sizes in a real book cluster into 3–10 distinct values (body text, headings, captions, footnotes). Collecting duplicates is wasteful.

## Proposed Solution

Use a set to deduplicate, then sort only the distinct values:

```python
all_sizes_set: set[float] = set()
for page in doc:
    ...
    for span in line["spans"]:
        text = span["text"].strip()
        if text:
            all_sizes_set.add(span["size"])

if not all_sizes_set:
    return []

median_size = statistics.median(sorted(all_sizes_set))
```

This reduces the sort from O(n log n) over millions of items to O(d log d) where d is the number of distinct sizes — typically 5–15.

## Technical Details

- **File:** `condensr/parser.py`
- **Lines:** 193–208

## Acceptance Criteria

- [ ] `all_sizes` changed from `list` to `set` (rename to `all_sizes_set` for clarity)
- [ ] `statistics.median(sorted(all_sizes_set))` used
- [ ] Existing heading-detection tests still pass
- [ ] No behavior change — same threshold, same output
