Fixes #9000 - #9014
Conversation
|
To show that this fixes the original issue, please report results from the linked benchmark test, at minimum. Thanks! |
perminder-17
left a comment
There was a problem hiding this comment.
The results are good, just one concern for the cleaner code.
| }); | ||
|
|
||
| return coords; | ||
| this.#rgbaCache.set(cacheKey, result); |
There was a problem hiding this comment.
I don't think we need this Map(). The only heavy step is the 'srgb' conversion you did above, so we can just cache that part, less complexity and cleaner code.
| } | ||
|
|
||
| _getRGBA(maxes=[1, 1, 1, 1]) { | ||
| const cacheKey = maxes.join(','); |
There was a problem hiding this comment.
maxes.join(',') allocates a new string on every call inside loops. Using a fast path key check for [255, 255, 255, 255] avoids string allocations during pixel loops.
|
|
||
| coords = coords.map((coord, i) => { | ||
| let coords; | ||
| if (this.mode === RGB) { |
There was a problem hiding this comment.
Use this._color.space.id === 'srgb' instead of this.mode === RGB makes the fast-path work for any color object backed by sRGB. It ensures that any color whose underlying color space is sRGB will bypass colorjs conversion and structuredClone, even if the color mode was initialized via another path.
|
All feedback are addressed and solved, thanks for your input @Ayush4958 and @perminder-17 |
ksen0
left a comment
There was a problem hiding this comment.
Nice work, thanks ! And thanks to reviewers!
Continuous ReleaseCDN linkPublished PackagesCommit hash: 7f4b60a Previous deploymentsThis is an automated message. |
limzykenneth
left a comment
There was a problem hiding this comment.
If I read the changes correctly, is it essentially memoizing the _getRGBA function? The implementation should be ok and functional but having a #invalidateSrgbCache can be a bit brittle in that we need to make sure that #invalidateSrgbCache is called on all possible code paths (including in the future) that changes the color somehow. If it is just some form of memoizing, can we create a memoization whose key is the color coordinates? Similar to what toString() uses ${this._color.space.id}-${this._color.coords.join(',')}-${this._color.alpha}-${format}?
There was a problem hiding this comment.
This file shouldn't be committed as it does not match the required format of the benchmark harness.
…es; remove all calls to #invalidateSrgbCache
limzykenneth
left a comment
There was a problem hiding this comment.
Looks good for now. If you can do a test with benchmarking to see if it affect performance or not that would be great. After that we can merge.
| if (srgbCoordsCache.size > 1000) { | ||
| srgbCoordsCache.delete(srgbCoordsCache.keys().next().value); | ||
| } |
There was a problem hiding this comment.
Good to have this. I wonder if 1000 is the right number? What would a typical number of colors set() would manipulate and what would be a sensible upper bound without it leaking memory?
There was a problem hiding this comment.
Typical sketches use far fewer than 1000 unique colors. However, image processing or complex generative art could exceed this. Each entry is small (~32 bytes), so 1000 entries ≈ 32KB max. I chose 1000 as a conservative default that covers most cases without significant memory impact. Would you prefer a different value or should we make it configurable?

Resolves #9000
set()onp5.Graphicswas significantly slower in 2.x vs 1.11.x because_getRGBAdid a fullto('srgb')+structuredClone+map()on everycall, even when the color was already in RGB mode and being reused in a
tight loop.
Changes:
_getRGBAresults#rgbaCacheMap onColor, keyed bymaxesstringmaxesreturn a shallow copy of the cached array
setRed,setGreen,setBlue,setAlpha,and the
_colorsetterthis.mode === RGB, coords are already sRGB 0-1, so skip theto('srgb')conversion and use[...this._color.coords, this._color.alpha]directly
AI usage disclosure: I used Kilo (an AI coding assistant) to help
implement and review this change. I understand and take responsibility for
every line of code in this PR. See [AI_USAGE_POLICY.md].
PR Checklist
npm run lintpasses