diff --git a/.jules/bolt.md b/.jules/bolt.md index d54cf10fc..b184c8933 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -61,3 +61,7 @@ ## 2026-07-13 - Array.from mapping optimization **Learning:** Using `Array.from({ length: N }).map(...)` creates an intermediate array of `undefined` values which requires memory allocation and garbage collection, adding O(N) unnecessary overhead in frequently re-rendered UI components. **Action:** Use `Array.from({ length: N }, (_, index) => ...)` to map elements directly during array creation, avoiding intermediate allocations. + +## 2026-07-20 - Eliminate intermediate list allocations in Python sum(zip(A, A[1:])) +**Learning:** Using `sum(1 for a, b in zip(list, list[1:]))` creates an intermediate list slice (`list[1:]`) and zip object, allocating O(N) memory and causing garbage collection overhead. +**Action:** Calculate the metric (e.g. state changes) inside the primary loop by caching the previous state in a local variable (e.g., `last_chord`) to achieve O(1) memory and avoid intermediate list slice allocations. diff --git a/services/analysis-engine/src/bandscope_analysis/chords/section_harmony.py b/services/analysis-engine/src/bandscope_analysis/chords/section_harmony.py index a61a7d001..b3447408f 100644 --- a/services/analysis-engine/src/bandscope_analysis/chords/section_harmony.py +++ b/services/analysis-engine/src/bandscope_analysis/chords/section_harmony.py @@ -84,14 +84,17 @@ def _summarize_one_section( the portion of their duration that overlaps the window. """ durations: dict[str, float] = {} - overlapping_chords: list[str] = [] + chord_changes = 0 + last_chord: str | None = None for seg_start, seg_end, chord in segments: overlap = min(seg_end, section_end) - max(seg_start, section_start) if overlap <= 0.0: continue durations[chord] = durations.get(chord, 0.0) + overlap - overlapping_chords.append(chord) + if last_chord is not None and last_chord != chord: + chord_changes += 1 + last_chord = chord chords: list[ChordDuration] = [ {"chord": chord, "duration": duration} @@ -104,12 +107,6 @@ def _summarize_one_section( main_chord = entry["chord"] break - chord_changes = sum( - 1 - for previous, current in zip(overlapping_chords, overlapping_chords[1:], strict=False) - if previous != current - ) - return { "start_time": section_start, "end_time": section_end,