Memoize Color Translations - #8055
Open
robertclaus wants to merge 2 commits into
Open
robertclaus wants to merge 2 commits into
robertclaus wants to merge 2 commits into
Conversation
archmoj
reviewed
Sep 18, 2026
| // Stop growing rather than evicting: a graph only ever uses a | ||
| // handful of distinct colors, so a full cache means array-valued | ||
| // colors, which repeat too little to be worth tracking. | ||
| if (cache.size < MAX_MEMO_SIZE) cache.set(cstr, value); |
Contributor
There was a problem hiding this comment.
When MAX_MEMO_SIZE reached one could evict first half of the cache.
You could split the cache into two separate Maps: currentCache and oldCache.
- Lookups check
currentCachefirst, thenoldCache(and move the item tocurrentCacheif found). - Writes only go to
currentCache. - When
currentCachereaches the maximum capacity limit, you simply wipeoldCacheentirely
oldCache.clear();and swap the references:
oldCache = currentCache;
currentCache = new Map();This provides a near-instantaneous O(1) bulk eviction without any loops.
Contributor
|
Thanks @robertclaus for the PR. |
Contributor
|
Please also double check the results using random marker colors. function generateRandomColors(count) {
const colors = [];
for (let i = 0; i < count; i++) {
// Generate a random number up to 16777215 (FFFFFF in hex)
// Convert it to base-16 and pad with leading zeros if it's shorter than 6 characters
const randomHex = Math.floor(Math.random() * 16777215)
.toString(16)
.padStart(6, '0');
colors.push(`#${randomHex}`);
}
return colors;
}
var gd = document.getElementById('graph');
var n = 1e5, x = new Float64Array(n), y = new Float64Array(n);
for (let i = 0; i < n; i++) { x[i] = i; y[i] = Math.sin(i / 500); }
var randomColors = generateRandomColors(n)
var runs = [];
for (let k = 0; k < 5; k++) {
await Plotly.purge(gd);
const t = performance.now();
await Plotly.newPlot(gd, [{type: 'scatter', mode: 'markers', marker: {color: randomColors}, x, y}],
{width: 900, height: 600}, {displayModeBar: false});
runs.push(+(performance.now() - t).toFixed(1));
}
runs.sort((a, b) => a - b);
console.log('median', runs[2], runs); |
archmoj
reviewed
Sep 18, 2026
| */ | ||
| const fill = (s, cstr) => { | ||
| s.style({ fill: rgb(cstr), 'fill-opacity': parse(cstr).alpha }); | ||
| s.style({ fill: rgb(cstr), 'fill-opacity': alphaOf(cstr) }); |
Contributor
There was a problem hiding this comment.
Alternatively instead of the cash we may benchmark this option of by passing previous stroke and previous fill. Something like this:
var prevStrokeSTR;
var prevStrokeRGB;
var prevStrokeAlpha;
function getStroke(cstr) {
if(prevStrokeSTR !== cstr) {
prevStrokeSTR = cstr;
prevStrokeRGB = rgb(cstr);
prevStrokeAlpha = parse(cstr).alpha;
}
return [prevStrokeRGB, prevStrokeAlpha];
}
const stroke = (s, cstr) => {
const v = getStroke(cstr);
s.style({ stroke: v[0], 'stroke-opacity': v[1] });
};
var prevFillSTR;
var prevFillRGB;
var prevFillAlpha;
function getFill(cstr) {
if(prevFillSTR !== cstr) {
prevFillSTR = cstr;
prevFillRGB = rgb(cstr);
prevFillAlpha = parse(cstr).alpha;
}
return [prevFillRGB, prevFillAlpha];
}
const fill = (s, cstr) => {
const v = getFill(cstr);
s.style({ fill: v[0], 'fill-opacity': v[1] });
};
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.
Fixes #8054
This PR adds memoization to the color string parsing functions. This way we do not need to re-parse the color strings for every single mark. Benchmarking indicates that this makes marker-heavy scatter charts render almost twice as quickly.
Testing
On both
mainand this branch, do the following:npm startto open the dashboard on port 3000.Note the difference in numbers.