From adec13fbbba7feaba4d975e0ea9a06606624fc61 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 25 Jul 2026 17:33:01 +0000 Subject: [PATCH] Memoize context lexicon compilation to improve clinical span processing performance. Co-authored-by: zrt219 <199104500+zrt219@users.noreply.github.com> --- .jules/bolt.md | 3 +++ openmed/openmed/clinical/context.py | 7 +++++++ 2 files changed, 10 insertions(+) create mode 100644 .jules/bolt.md diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000..5290c47 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2024-07-25 - Context Lexicon Compilation Bottleneck +**Learning:** Deterministic regex generation for clinical span lexicons (`_compiled_context_lexicon` in `openmed/clinical/context.py`) is expensive and is repeatedly invoked by various helpers (e.g. `is_negated`, `is_hypothetical`). Since the language argument is hashable, caching this generation avoids massive repetitive computation. +**Action:** Always verify if computationally heavy dynamic regex generation based on statically loadable parameters (like a language code or fixed taxonomy) is being done per-span, and aggressively memoize these functions (`@functools.lru_cache`) to avoid re-compilation. diff --git a/openmed/openmed/clinical/context.py b/openmed/openmed/clinical/context.py index 9fd11df..7ae9812 100644 --- a/openmed/openmed/clinical/context.py +++ b/openmed/openmed/clinical/context.py @@ -39,6 +39,7 @@ from collections.abc import Iterable, Iterator, Mapping, Sequence from dataclasses import dataclass, replace from datetime import date +from functools import lru_cache from typing import Any, Literal from openmed.clinical.lexicons import ( @@ -154,7 +155,13 @@ class _CompiledContextLexicon: backward_context_cues: frozenset[str] +@lru_cache(maxsize=16) def _compiled_context_lexicon(language: str | None = None) -> _CompiledContextLexicon: + """Returns regex matchers derived from the context cues lexicon. + + Memoized as cue sets can be large to iterate and regexes are expensive + to compile across many invocations. + """ lexicon = get_clinical_cue_lexicon(language) token_boundaries = lexicon.token_boundaries return _CompiledContextLexicon(