-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve performance canvas heatmap #574
Conversation
The update delay can be specified.
…r than using jQUery's css function. This reduces a bit of jitter when panning a rotated heat map.
This will only change if the data changes or the projection changes, which will cause it to be recomputed then. Otherwise, this reduces update time by 10% of so.
Switching the core drawImage loop sped up large datasets by 40% or so.
Precalculating position must always be done, too.
ea28230
to
f52faa5
Compare
Fixes #574 with many minor tweaks and one major tweak to get the max performance for canvas heatmap. Few other changes (binning, gaussian circle etc.) will be upcoming in separate PRs. |
Current coverage is 72.78%@@ master #574 diff @@
==========================================
Files 82 82
Lines 7074 7128 +54
Methods 0 0
Messages 0 0
Branches 0 0
==========================================
+ Hits 5076 5188 +112
+ Misses 1998 1940 -58
Partials 0 0
|
During the development of this code, I did some timing tests on my desktop: Rendering time for the heatmap in Chrome:
Firefox is slower. Of this, around 75 or 80% of the time is spent in This excludes the benefits of debouncing the rendering. |
@aashish24 Do you have any machines that exercise the big-endian code? |
No I don't. The code piece I got inspiration from had done something but I don't know how thorough it was. |
if (m_typedBuffer[4] === 0x0a && | ||
m_typedBuffer[5] === 0x0b && | ||
m_typedBuffer[6] === 0x0c && | ||
m_typedBuffer[7] === 0x0d) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I try this out in the Chrome console, it doesn't work. m_typedBuffer
references an ArrayBuffer
, which doesn't give me index reference access to the array. I think this comparison needs to be on the m_typedClampedBuffer
, not on m_typedBuffer
. What is here works, but only because we've only tried in on little-endian machines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. let me have a look at it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@manthey yes, it should be on clamped buffer, thanks for report this. I pushed a fix.
Earlier looking at the wrong buffer on which indexing was undefined
@aashish24 In thinking about this further, won't this mess up the gradient on a big-endian machine because it will switch the color channels? Specifically, in The original (non-typed) behavior was only slower than the current code because it called |
I don't think so? Since gradient index look will give us the right value but we need to write that value that we get from gradient to the right offset. Too bad that jsperf is down or else we could have tested it with some simple code (performance). The original author claimed that in the general it performed faster. |
it was reported that firefox folks has seen quite a bit of performance improvement (but I cannot confirm now since jsperf is under renovation): https://jsperf.com/canvas-pixel-manipulation/6. I am wondering are there any big endian machine left? https://news.ycombinator.com/item?id=9451284 |
bd4e7cb
to
8f25c0a
Compare
This is slightly faster because it operates on 32 bit values instead of 8 bit values. For 100,000 points in a controlled test, the average render time went from 517.7 ms to 499.5 ms (a 3.5% improvement). Additionally, there is only one code path, rather than two, which simplifies testing.
@aashish24 I made a simplification that is slightly faster and no longer needs separate code paths for different endians. |
m_typedBuffer = new ArrayBuffer(imageData.data.length); | ||
this._colorize = function (pixels, gradient) { | ||
var grad = new Uint32Array(gradient.buffer); | ||
var i, j, k, pixlen = pixels.length; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we remove the other var (to be consistent). Also I was told that fewer vars declarations is better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll make it so there is just one statement.
I'd be shocked if there is a measurable performance difference between single and multiple var statements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The one var
rule comes from jslint. I think the justification for it is preventing C programmers from misunderstanding how scoping rules work in javascript. My preference is just to keep all of the variable declarations at the top of the function, but I don't think enforcing a one var
rule is worthwhile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Roger that. I think most of our code is one var and declarations are on top of the function. As far as we are consistent, I am good.
Every layer has an opacity property. Unless there is a real need to have multiple features in the same layer with different per-feature opacities, I think we should stick with the current model.
less is better. I will have a look. How did you capture the performance? |
I am using my modified example where I can load an arbitrary number of points. I loaded 100,000 points. I then used chrome's console to render the same frames in a predictable way: Note that Chrome is slower if the computer is busy doing something else, so make sure this is the only cpu-intensive process for consistent results. |
Fix some of the documentation.
Fix an issue where a transform of a zero length array would throw an error.
@aashish24 This now has complete test coverage. At this point, I think you should do review and decide if it is ready for merge. |
LGTM 👍 |
No description provided.