diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000..e8b5081 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2024-05-24 - [Cache Unnecessary Python Loop Variables] +**Learning:** In highly recursive or looping NLP functions such as line-by-line regex scanning, rebuilding configurations or alias lookups dynamically creates enormous overhead in Python. The openmed package's `_alias_lookups` recreated language alias dicts on every single line, leading to severe slowdowns. +**Action:** Use `@functools.lru_cache(maxsize=None)` on deterministic configuration generators within loops to cut down redundant operations. Ensure inputs are hashable and small in variance (like language codes). diff --git a/openmed/openmed/clinical/sections/detect.py b/openmed/openmed/clinical/sections/detect.py index 8716746..1d9b637 100644 --- a/openmed/openmed/clinical/sections/detect.py +++ b/openmed/openmed/clinical/sections/detect.py @@ -2,6 +2,7 @@ from __future__ import annotations +import functools from collections.abc import Iterable, Mapping from dataclasses import dataclass from typing import Any @@ -244,6 +245,9 @@ def _is_underline(text: str) -> bool: return len(stripped) >= 3 and set(stripped) <= _UNDERLINE_CHARS +# Bolt ⚡: Cache alias lookups as they are static per language to prevent +# redundant tuple/dict allocations on every line during clinical section detection. +@functools.lru_cache(maxsize=None) def _alias_lookups(language: str | None) -> tuple[tuple[str, Mapping[str, str]], ...]: languages = ( tuple(dict.fromkeys((get_section_lexicon(language).language, "en"))) diff --git a/openmed/uv.lock b/openmed/uv.lock index 78f4815..430a3da 100644 --- a/openmed/uv.lock +++ b/openmed/uv.lock @@ -4439,6 +4439,7 @@ wheels = [ name = "openmed" source = { editable = "." } dependencies = [ + { name = "defusedxml" }, { name = "faker" }, { name = "pysbd" }, { name = "pyyaml" }, @@ -4622,6 +4623,7 @@ requires-dist = [ { name = "coremltools", marker = "extra == 'coreml'", specifier = ">=8.0" }, { name = "dask", extras = ["dataframe"], marker = "extra == 'dask'", specifier = ">=2024.8" }, { name = "dask", extras = ["dataframe"], marker = "extra == 'dev'", specifier = ">=2024.8" }, + { name = "defusedxml", specifier = ">=0.7.1" }, { name = "duckdb", marker = "extra == 'dev'", specifier = ">=1.0,<2" }, { name = "duckdb", marker = "extra == 'duckdb'", specifier = ">=1.0,<2" }, { name = "easyocr", marker = "extra == 'multimodal'", specifier = ">=1.7" },