diff --git a/.jules/bolt.md b/.jules/bolt.md index 4f20b36047..fff4daacfa 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -54,3 +54,4 @@ ## 2026-09-01 - 대용량 문자열 서브스트링 스캐닝 루프 최적화 **Learning:** 긴 텍스트에서 여러 기준 문자열(`candidate`)을 탐색하여 다음 구역의 시작점을 찾을 때, 텍스트 전체에 대해 반복적으로 `text.find(candidate)`를 호출하면 O(N)의 비효율적인 중복 스캐닝 오버헤드가 발생합니다. 특히 가장 가까운 시작점을 찾기 위해 모든 후보를 스캔할 때 이 문제가 심화됩니다. **Action:** 기준점(`start`)을 잡은 후, `idx = text.find(candidate, start, end)`를 사용하여 검색 범위를 동적으로 축소(`end = min(end, idx)`)하십시오. 이렇게 하면 불필요한 스캐닝 오버헤드를 막고 검색 범위를 안전하게 줄여 매우 큰 성능 향상을 얻을 수 있습니다. +## 2026-09-05 - Python re.compile() Caching Overhead Measurement\n**Learning:** While pre-compiling regular expressions using `re.compile()` at the module level is idiomatic and visually cleaner, benchmarking shows negligible runtime difference (often under 1ms or lost in noise) for functions that compile a static string once per *call* (rather than per-iteration in a loop) because Python internally memoizes recently compiled patterns (up to 512 entries). This makes hoisting them purely a style improvement rather than a critical performance optimization.\n**Action:** When extracting `re.compile()` calls to module constants, document them as style or idiomatic improvements rather than making unverified claims about significant performance overhead. diff --git a/scripts/ci/implementation_completeness_scan.py b/scripts/ci/implementation_completeness_scan.py index 666623835d..866e42e1c5 100644 --- a/scripts/ci/implementation_completeness_scan.py +++ b/scripts/ci/implementation_completeness_scan.py @@ -10,6 +10,8 @@ from pathlib import Path from typing import Iterable +RUST_FN_PATTERN = re.compile(r"\bfn\s+([A-Za-z_][A-Za-z0-9_]*)") +RUST_MACRO_PATTERN = re.compile(r"\b(todo|unimplemented)\s*!") RUNTIME_TEST_PARTS = { "test", @@ -249,11 +251,10 @@ def rust_code_lines(source: str) -> list[tuple[int, str]]: def nearest_rust_symbol(code_lines: list[tuple[int, str]], line_no: int) -> str: """Return the nearest preceding Rust function name for a finding.""" - fn_pattern = re.compile(r"\bfn\s+([A-Za-z_][A-Za-z0-9_]*)") for current_line_no, code in reversed(code_lines): if current_line_no > line_no: continue - match = fn_pattern.search(code) + match = RUST_FN_PATTERN.search(code) if match: return match.group(1) return "rust module" @@ -264,9 +265,8 @@ def scan_rust_file(repo_root: Path, relative_path: Path) -> list[Finding]: source_path = repo_root / relative_path code_lines = rust_code_lines(source_path.read_text(encoding="utf-8")) findings: list[Finding] = [] - macro_pattern = re.compile(r"\b(todo|unimplemented)\s*!") for line_no, code in code_lines: - for match in macro_pattern.finditer(code): + for match in RUST_MACRO_PATTERN.finditer(code): macro_name = match.group(1) findings.append( Finding( @@ -305,7 +305,9 @@ def scan_changed_paths( return findings, errors -def render_report(findings: list[Finding], errors: list[str], checked_count: int) -> str: +def render_report( + findings: list[Finding], errors: list[str], checked_count: int +) -> str: """Render a markdown report for CI logs and review evidence.""" lines = [ "# Implementation Completeness Scan",