From 32a8e8fc6476de6aabff31dbb66402b2e7ed38de Mon Sep 17 00:00:00 2001 From: Serafim Barroca Date: Wed, 5 May 2021 12:20:32 +0100 Subject: [PATCH 1/2] Address performance issue with ArrayBuffers Address an unavoidable loop phase inside color clean function where it iterates all over the graph points if data used is an ArrayBuffer. This causes graph to have way less performance relative to Array types. --- src/components/color/index.js | 2 +- src/traces/scattergl/calc.js | 16 +++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/components/color/index.js b/src/components/color/index.js index 99cae2d12f2..a6656058c65 100644 --- a/src/components/color/index.js +++ b/src/components/color/index.js @@ -116,7 +116,7 @@ color.clean = function(container) { if(!Array.isArray(el0) && el0 && typeof el0 === 'object') { for(j = 0; j < val.length; j++) color.clean(val[j]); } - } else if(val && typeof val === 'object') color.clean(val); + } else if(val && typeof val === 'object' && !ArrayBuffer.isView(val)) color.clean(val); } }; diff --git a/src/traces/scattergl/calc.js b/src/traces/scattergl/calc.js index 54069477f21..b090ee48bcd 100644 --- a/src/traces/scattergl/calc.js +++ b/src/traces/scattergl/calc.js @@ -27,7 +27,7 @@ module.exports = function calc(gd, trace) { var hasTooManyPoints = len >= TOO_MANY_POINTS; var len2 = len * 2; var stash = {}; - var i, xx, yy; + var i; var origX = xa.makeCalcdata(trace, 'x'); var origY = ya.makeCalcdata(trace, 'y'); @@ -42,11 +42,12 @@ module.exports = function calc(gd, trace) { // we need hi-precision for scatter2d, // regl-scatter2d uses NaNs for bad/missing values var positions = new Array(len2); + var _ids = new Array(len); for(i = 0; i < len; i++) { - xx = x[i]; - yy = y[i]; - positions[i * 2] = xx === BADNUM ? NaN : xx; - positions[i * 2 + 1] = yy === BADNUM ? NaN : yy; + positions[i * 2] = x[i] === BADNUM ? NaN : x[i]; + positions[i * 2 + 1] = y[i] === BADNUM ? NaN : y[i]; + // Pre-compute ids. + _ids[i] = i; } if(xa.type === 'log') { @@ -66,10 +67,7 @@ module.exports = function calc(gd, trace) { // FIXME: delegate this to webworker stash.tree = cluster(positions); } else { - var ids = stash.ids = new Array(len); - for(i = 0; i < len; i++) { - ids[i] = i; - } + stash.ids = _ids; } // create scene options and scene From f8d552e734f1ded9ee5e85670ef8dd0e4f2bf130 Mon Sep 17 00:00:00 2001 From: Serafim Barroca Date: Wed, 5 May 2021 14:29:11 +0100 Subject: [PATCH 2/2] Check for TypeArray instead of ArrayBuffer --- src/components/color/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/color/index.js b/src/components/color/index.js index a6656058c65..c10ce0b1d4a 100644 --- a/src/components/color/index.js +++ b/src/components/color/index.js @@ -2,6 +2,7 @@ var tinycolor = require('tinycolor2'); var isNumeric = require('fast-isnumeric'); +var isTypedArray = require('../../lib/array').isTypedArray; var color = module.exports = {}; @@ -116,7 +117,7 @@ color.clean = function(container) { if(!Array.isArray(el0) && el0 && typeof el0 === 'object') { for(j = 0; j < val.length; j++) color.clean(val[j]); } - } else if(val && typeof val === 'object' && !ArrayBuffer.isView(val)) color.clean(val); + } else if(val && typeof val === 'object' && !isTypedArray(val)) color.clean(val); } };