perf(dashboard): single-resolve render data cache for populated dashboard load (260610-ov3)#202
Merged
Merged
Conversation
… cache - test_cache_property_exists: getRenderCacheForTest_ seam cold on construction - test_resolve_count_le_1: at most 1 getXY call per render() pass - test_bound_array_parity: inner line XData equals raw tag X (no corruption) - test_cache_cold_after_render: RenderDataCache_ is cleared after render()
…Widget 260610-ov3: resolve Tag data at most once per render()/rebuildForTag_() pass. - Add RenderDataCache_ private property (render-scoped struct or []) - Add pullDataCached_() — returns warm cache or calls pullData_() + caches - Add cacheRenderData_(x,y) — stores struct into RenderDataCache_ - Add clearRenderCache_() — resets to [] at end of render/rebuild pass - render(): probe result seeds cache; branch (3) uses pullDataCached_() + fp.addLine (State tags keep fp.addTag via getKind guard); yInit and updateTimeRangeCache reuse cached x/y; clearRenderCache_() at end - rebuildForTag_(): same single-resolve + cached updateTimeRangeCache; clearRenderCache_() at end - getRenderCacheForTest_() / setRenderCacheForTest_() Hidden seams for tests - refresh()/update() untouched — live tick fast path is unaffected
…load perf 260610-ov3 Task 2 RED gate: - CountingSensorTag.m — SensorTag subclass that counts getXY() invocations - test_dashboard_load_perf.m — 5 cases: - test_resolve_count_le_1: CountingSensorTag asserts <= 1 resolve per render - test_bound_array_parity: line XData endpoints within raw tag X range - test_preview_parity: warm-cache vs cold-cache getPreviewSeries byte-identical - test_cache_cold_after_render: RenderDataCache_ is [] after render completes - test_state_tag_fallback: StateTag staircase path still works via getKind guard
260610-ov3 Task 2: Part A — getPreviewSeries (FastSenseWidget.m): Reuses RenderDataCache_ read-only when warm (load-time preview pass). Falls back to Tag.getXY() when cold (live ticks) — behavior unchanged. Eliminates one extra getXY resolve per widget at dashboard render time. Part B — benchmarks/bench_dashboard_load.m: New benchmark isolating dashboard LOAD (Create+Render) for Tag-bound widgets. Builds N_TAGS=12 SensorTags (50k pts each), converts ~1/3 to disk-backed via toDisk(), wires N_EVENTS=200 in-memory EventStore to first widget. Prints Create / Render / Total ms matching bench_dashboard.m label style. Complements bench_dashboard.m (inline XData) and bench_dashboard_live.m (live ticks); isolates the disk-backed/Tag-bound render hot path.
…pull O(1) The executor's render cache was cleared at the end of widget render(), before DashboardEngine's post-render preview pass — so the preview reuse was dead code and the constructor still did a full Tag.getXY() pull: - updateTimeRangeCache() no-arg now asks Tag.getTimeRange() (O(1) for Sensor/State tags; disk-backed reads the DataStore extent, which also fixes the ctor leaving CachedXMin/Max at inf/-inf for disk tags) - render() leaves the cache warm; getPreviewSeries consumes it (consume-once); refresh()/update() clear it on entry so live ticks never read render-scoped data - setRenderCacheForTest_([], []) clears (test seam) - tests updated to the lifecycle contract; StateTag test used the invalid 'States' option — now 'Labels' Verified in Octave 11.1: test_fastsense_widget_render_cache 4/4, test_dashboard_load_perf 5/5, 13 dashboard/widget regression tests OK. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…Sense dashboards (DashboardEngine) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Optimizes the data-loading slice of populated Tag-bound dashboard loads (quick task 260610-ov3). Complements the live-tick perf passes (260609-v5p, 260610-g0w) — this targets the first
render()pass.RenderDataCache_inFastSenseWidget: one render pass previously resolved the same Tag data 3–4× (bind, Y-autoscale, time-range cache, engine preview pass). Now resolved once and reused. State tags keep thefp.addTagstaircase path via agetKind=='state'guard.DashboardEngine's post-rendercomputePreviewEnvelopepass, is cleared on the preview read, andrefresh()/update()clear it on entry — live ticks never see render-scoped data.updateTimeRangeCache()no-arg now usesTag.getTimeRange()instead of a fullgetXY(); also fixes disk-backed tags gettinginf/-inftime range at construction.benchmarks/bench_dashboard_load.m(12 tags × 50k pts, 4 disk-backed): Render 6834 → 6711 ms, Create 142 → 123 ms (Octave, graphics-bound — the data-fetch slice is what halved).No
DashboardWidgetcontract change (additive private state + Hidden test seams only); pure MATLAB, no new dependencies; serialized dashboards unaffected.Test plan
tests/test_fastsense_widget_render_cache.m4/4 — resolve count ≤1 proven viaCountingSensorTagtests/test_dashboard_load_perf.m5/5 — bound-array parity, preview parity warm vs cold, cache lifecycle, StateTag staircasemh_lint+mh_stylecleanTestDashboardEngine,TestFastSenseWidgetUpdate,TestDashboardSerializerRoundTrip) — deferred, MATLAB MCP down this session (follow-up chip spawned)🤖 Generated with Claude Code