Skip to content

Commit 56d3b01

Browse files
authored
Merge pull request #809 from nteract/heatmap-perf
Improve heatmap bin perf
2 parents a38452c + 4f1ccd7 commit 56d3b01

8 files changed

Lines changed: 440 additions & 322 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515
- **Dev-mode `d.data` access warning** — Frame callbacks (`nodeStyle`, `edgeStyle`, `nodeSize`) now warn in development when users access properties that exist on `.data` but not on the RealtimeNode/RealtimeEdge wrapper (e.g., `d.category` instead of `d.data?.category`). Zero production overhead. Applied to all 5 layout plugins (sankey, force, chord, orbit, hierarchy).
1616
- **Streaming-first docs narrative** — Landing page and Getting Started page restructured to lead with the streaming engine (push API, two-canvas RAF loop, ring buffer, decay/pulse/staleness/transitions) as the primary differentiator.
1717

18+
### Performance
19+
20+
- **Heatmap scene builder optimized** — Streaming path uses flat `Int32Array`/`Float64Array` grids instead of `Map<string, {data[]}>`, eliminating 50k string key allocations and per-datum array pushes. Static path uses numeric Map keys and precomputed 256-entry color LUT (cached per scheme) instead of per-cell `scaleSequential` calls. Streaming 50k points into 20×20 grid: **0.37ms** (was ~49ms with Map+string approach). Static path ~15% faster at high cardinality.
21+
1822
### Fixed
1923

2024
- **`@modelcontextprotocol/sdk` removed from production dependencies** — The MCP CLI (`semiotic-mcp`) now bundles the SDK via esbuild, so `npm install semiotic` no longer pulls in the 4MB+ MCP SDK and its transitive deps. The bundled CLI works identically — zero behavior change for `npx semiotic-mcp` users.

benchmarks/unit/render-pipeline.bench.ts

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -162,27 +162,56 @@ describe('Scene Builders — Stacked Area', () => {
162162
})
163163
})
164164

165-
describe('Scene Builders — Heatmap', () => {
165+
describe('Scene Builders — Heatmap (static)', () => {
166166
const ctx = makeCtx({
167167
config: {
168-
heatmapXBins: 20,
169-
heatmapYBins: 20,
168+
xAccessor: 'x',
169+
yAccessor: 'y',
170+
valueAccessor: 'value',
170171
},
171172
})
172173

173-
bench('heatmap-1k', () => {
174+
bench('heatmap-static-1k', () => {
174175
buildHeatmapScene(ctx, scatter1k, defaultLayout)
175176
})
176177

177-
bench('heatmap-10k', () => {
178+
bench('heatmap-static-10k', () => {
178179
buildHeatmapScene(ctx, scatter10k, defaultLayout)
179180
})
180181

181-
bench('heatmap-50k', () => {
182+
bench('heatmap-static-50k', () => {
182183
buildHeatmapScene(ctx, scatter50k, defaultLayout)
183184
})
184185
})
185186

187+
describe('Scene Builders — Heatmap (streaming aggregation)', () => {
188+
const ctx20 = makeCtx({
189+
config: { heatmapAggregation: 'count', heatmapXBins: 20, heatmapYBins: 20, valueAccessor: 'value' },
190+
})
191+
const ctx50 = makeCtx({
192+
config: { heatmapAggregation: 'count', heatmapXBins: 50, heatmapYBins: 50, valueAccessor: 'value' },
193+
})
194+
const ctx100 = makeCtx({
195+
config: { heatmapAggregation: 'mean', heatmapXBins: 100, heatmapYBins: 100, valueAccessor: 'value' },
196+
})
197+
198+
bench('heatmap-stream-10k-20x20', () => {
199+
buildHeatmapScene(ctx20, scatter10k, defaultLayout)
200+
})
201+
202+
bench('heatmap-stream-50k-20x20', () => {
203+
buildHeatmapScene(ctx20, scatter50k, defaultLayout)
204+
})
205+
206+
bench('heatmap-stream-50k-50x50', () => {
207+
buildHeatmapScene(ctx50, scatter50k, defaultLayout)
208+
})
209+
210+
bench('heatmap-stream-50k-100x100-mean', () => {
211+
buildHeatmapScene(ctx100, scatter50k, defaultLayout)
212+
})
213+
})
214+
186215
// ── 2. RingBuffer Operations ───────────────────────────────────────────────
187216

188217
describe('RingBuffer — Push Throughput', () => {

0 commit comments

Comments
 (0)