Benchmarks
PowerPoint library benchmarks, measured on real decks.
pptxboss against office-oxide, kreuzberg, undoc, python-pptx and markitdown on text extraction over the .pptx test suites of five open-source projects, two real-world decks and the legacy .ppt test files, with a correctness gate in front of every timing. Every number below comes from the harness in the repository, and every table is reproducible.
Text extraction over 631 test-suite decks, all cores: 3.1× the next fastest Rust engine, 20× python-pptx.
The same on one thread, the like-for-like row: 2.5× office-oxide, 16× python-pptx.
To read the text of a 43-slide, 42 MB deck, against office-oxide’s 4.89 ms.
Paragraph-for-paragraph with python-pptx on every file the comparison includes.
Text extraction
631 .pptx test-suite files · 1,370 slides · files per second, higher is better
Slides per second tell the same story: 21,424 on all cores and 17,243 on one thread against office-oxide’s 6,867. Both pptxboss rows include chart and SmartArt text, which no other engine measured produces; on this corpus that costs 13% of the one-thread time.
| Deck | office-oxide | pptxboss, one thread | pptxboss, all cores |
|---|---|---|---|
| 43 slides, 42 MB, wall | 4.89 ms | 1.38 ms | 0.44 ms |
| 43 slides, 42 MB, CPU | 5.19 ms | 1.41 ms | 2.60 ms |
| 7 slides, 3 MB, wall | 1.05 ms | 0.28 ms | 0.16 ms |
| 7 slides, 3 MB, CPU | 1.10 ms | 0.28 ms | 0.52 ms |
Wall time is what a caller waits; CPU time is what the machine spends. On one thread pptxboss does the 43-slide deck in 27% of office-oxide’s CPU time.
Legacy .ppt decks
153 PowerPoint 97-2003 files, 41 MB · total time on one thread, lower is better
Best of 3 per file over the readable .ppt files of the LibreOffice and Apache POI test suites. One thread is the default for a legacy deck in pptxboss. The words agree on 87 of the 89 decks that contain text.
| Check | Result | Fine print |
|---|---|---|
| Paragraph agreement with python-pptx | 636 of 636 gated files | Per-slide paragraphs compared after whitespace normalization; no file excluded for a disagreement. |
| Files passing the gate | 636 of 737 | The other 101 are listed with a reason: 94 python-pptx could not open (86 of them Strict-namespace decks), 5 with a slide or chart pptxboss reports unreadable, 1 encrypted, 1 not a presentation package. |
| Legacy .ppt word agreement with office-oxide | 87 of 89 decks with text | The other two have a broken user-edit chain that pptxboss recovers only partially. office-oxide includes master placeholder text; pptxboss never does. |
| Verifier on PowerPoint-authored decks | 0 findings | Rules that fired on the public corpus fell into fuzzer-minimized garbage, hand-made test files and files written by other libraries; those results set the severities. |
A file counts toward a timing only when pptxboss reports nothing skipped and its paragraphs match python-pptx. Speed measured on wrong output would mean nothing, so the gate runs first.
Method
How the numbers were taken.
Corpus. The 737 .pptx files of the LibreOffice, Apache POI, python-pptx, pandoc and Open XML SDK test suites, fetched by a script in the repository; nothing is checked in, and results record counts and rates, never file names. Test-suite files are small, so the rows are dominated by per-file cost.
Gate. A file counts only when pptxboss reports nothing skipped and its per-slide paragraphs match python-pptx after whitespace normalization: 636 files pass, and not one is excluded for a disagreement. The 101 exclusions are listed with a reason in the results file: 94 that python-pptx could not open, 86 of them Strict-namespace decks, 5 where pptxboss reports a slide or chart it cannot read, one encrypted deck and one file that is not a presentation package. Files any engine fails on are excluded from every row, which leaves 631 files and 1,370 slides in common.
Timing. Every engine is called from Python through its own adapter. One warm-up pass, then best of 3 per file, aggregated over the common files, all rows from one session on an Apple M3 Pro. pptxboss spreads a deck’s slides across cores unless threads=1 keeps it on the calling thread; the one-thread row is the like-for-like comparison, since the other Rust engines run one thread per file (office-oxide’s wheel was measured at 0.9 to 1.1 CPU seconds per wall second). The pptxboss rows include chart and SmartArt text, which none of the other engines produce; on this corpus that costs 13% of the one-thread time, and text(charts=False, diagrams=False) leaves it out.
Real-world decks. Two PowerPoint decks of 7 and 43 slides (3 MB and 42 MB), the same harness, best of 40, wall and CPU time both recorded.
Legacy .ppt. The 153 readable .ppt files of the LibreOffice and Apache POI test suites (41 MB), best of 3 per file, both engines on one thread, which is the default for a legacy deck in pptxboss. The words agree on 87 of the 89 decks that contain text; the other two have a broken user-edit chain that pptxboss recovers only partially. office-oxide includes master placeholder text and pptxboss never does.
Absolute numbers depend on the machine and on the cores macOS schedules the process on; ratios between engines hold within about 20% across sessions. Compare rows against each other, and reproduce them with benchmarks/bench.py in the repository. Engine versions are recorded in benchmarks/results.json.
What is not measured
Where the tables stop.
- The paragraph comparison is against python-pptx only, because the other engines do not expose per-slide paragraphs.
- Markdown output is not scored against the other engines' Markdown; the tables measure text extraction.
- No rendering is compared, because pptxboss does not render slides to images.
- Deck creation and the verifier are not timed.