Skip to content

perf(odt): index automatic styles for style lookups (1.6x-3.2x on Word-exported ODT) - #4881

Merged
dolfim-ibm merged 1 commit into
docling-project:mainfrom
deadstrobe5:perf-odt-style-index
Oct 19, 2026
Merged

dolfim-ibm merged 1 commit into
docling-project:mainfrom
deadstrobe5:perf-odt-style-index

Conversation

@deadstrobe5

Copy link
Copy Markdown
Contributor

Follow-up to #4867, where @ExtReMLapin asked whether the ODF backend could use the same treatment. I first assumed the per-run text-style property reads were the cost, but caching those did nothing measurable on real files. Most of the time went into style lookups. get_style is already cached per (family, name), but each miss still goes through odfdo, which runs //office:font-face-decls and //office:automatic-styles over the whole content.xml and then scans every automatic style for a match. ODT files exported from Word carry several hundred to over a thousand automatic styles, so conversion ends up quadratic in practice.

This adds a small index over the content.xml automatic styles (built lazily on the first lookup, first match in document order, same as odfdo) for the families the backend asks for, and caches get_element on the content and styles parts so the container queries run once. Anything outside the index falls back to the original odfdo call.

CPU time per conversion, A/B in one process, 9 interleaved rounds with alternating order, median [min-max] in ms:

file (public gov.uk / LibreOffice docs) exported by before after speedup
ESA info leaflet Word 853.7 [826-900] 263.3 [258-289] 3.24x
Crown Proceedings Ordinance 1990 Word 806.4 [731-840] 374.8 [316-402] 2.15x
OPG130 raise a concern Word 761.4 [535-944] 327.4 [222-352] 2.33x
BBFA business regulation Word 1171.3 [745-1409] 500.9 [425-710] 2.34x
structure June FAQ Word 151.7 [135-178] 96.5 [81-124] 1.57x
LibreOffice Writer Guide ch. 4 LibreOffice 866.2 [669-897] 797.5 [686-888] 1.09x

LibreOffice-authored files with few automatic styles are roughly unchanged (the repo's own test files are within noise), and image-heavy ones stay dominated by PNG encoding in docling-core.

Checklist:

  • Documentation has been updated, if necessary.
  • Examples have been added, if necessary.
  • Tests have been added, if necessary.

Review evidence:

Output is unchanged: export_to_dict() JSON and export_to_markdown() are byte-identical before and after on 51 files (all ODT/ODS/ODP sources under tests/data/odf/sources, larger synthetic copies of them, 5 LibreOffice Writer Guide chapters and 40 ODTs from gov.uk). No reference data changed. pytest tests/test_backend_opendocument.py passes (61 tests), and prek run --files docling/backend/opendocument_backend.py passes (ruff, ty, tach, max lines).

Signed-off-by: Afonso Ribeiro <afonso.diamantino2@gmail.com>
@github-actions

Copy link
Copy Markdown
Contributor

✅ DCO Check Passed

Thanks @deadstrobe5, all your commits are properly signed off. 🎉

@mergify

mergify Bot commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🟢 Merge protection satisfied — ready to merge.

Show 1 satisfied protection

🟢 Enforce conventional commit

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert)(?:\(.+\))?(!)?:

@github-actions github-actions Bot added ai:ci-safe AI triage found no CI-safety concern (advisory) odf Issue related to the OpenDocument format (ODT, ODS, ODP) backend performance labels Oct 18, 2026
@github-actions

Copy link
Copy Markdown
Contributor

AI triage (advisory)

Checked commit 7d7a54ca9a. The analysis read the diff only. It did not run code from this pull request.

The PR adds a lazy index of the automatic styles in content.xml to the ODF backend. It also caches get_element on the content and styles parts to speed up style lookups.

Topic labels added: performance, odf.

CI safety: no concern found. A maintainer must still approve CI.

The ai:* labels are advisory. They do not approve CI and they do not add tests:full. A new push runs this check again.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI first review (advisory): no blocker found

This review covers the full diff at 7d7a54ca9a. It read the code and did not run it.

The index and cache are logically sound. The monkey-patching order is correct: get_element is cached before _build() can run. All three backends (ODT, ODS, ODP) receive the change through _OdfBaseBackend. The existing tests use LibreOffice-authored files with few automatic styles; they pass through the new code but do not exercise the high-automatic-style path that triggers the fix. No wrong behavior is visible in the diff. The human reviewer should confirm that the behavior on a Word-exported ODT with many automatic styles is covered by at least one test, or accept that the benchmark numbers in the PR description are sufficient evidence.

A maintainer makes the merge decision. This review never approves the pull request.

Comment thread docling/backend/opendocument_backend.py
@github-actions github-actions Bot added the ai:review-lgtm AI first review found no blocker or major issue (advisory) label Oct 18, 2026
@ExtReMLapin

Copy link
Copy Markdown
Contributor

One more step towards a faster docling !

@codecov

codecov Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.84848% with 5 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
docling/backend/opendocument_backend.py 84.84% 2 Missing and 3 partials ⚠️

📢 Thoughts on this report? Let us know!

@dolfim-ibm dolfim-ibm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@dolfim-ibm
dolfim-ibm merged commit 0b62ddd into docling-project:main Oct 19, 2026
33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai:ci-safe AI triage found no CI-safety concern (advisory) ai:review-lgtm AI first review found no blocker or major issue (advisory) odf Issue related to the OpenDocument format (ODT, ODS, ODP) backend performance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants