From e83dbecd96616f45d87799e7c59141a5388a6e05 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 16 Jun 2025 16:20:57 -0400 Subject: [PATCH 01/46] add performance tests --- .circleci/config.yml | 25 ++++++ .circleci/test.sh | 5 ++ package.json | 1 + tasks/test_performance.js | 46 ++++++++++ tasks/util/constants.js | 1 + test/jasmine/karma.conf.js | 19 +++- test/jasmine/performance_tests/bar_test.js | 89 +++++++++++++++++++ .../jasmine/performance_tests/scatter_test.js | 87 ++++++++++++++++++ 8 files changed, 269 insertions(+), 4 deletions(-) create mode 100644 tasks/test_performance.js create mode 100644 test/jasmine/performance_tests/bar_test.js create mode 100644 test/jasmine/performance_tests/scatter_test.js diff --git a/.circleci/config.yml b/.circleci/config.yml index b5d94298735..6701dd7e259 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -33,6 +33,28 @@ jobs: paths: - plotly.js + performance-jasmine: + docker: + # need '-browsers' version to test in real (xvfb-wrapped) browsers + - image: cimg/node:18.20.4-browsers + environment: + # Alaska time (arbitrary timezone to test date logic) + TZ: "America/Anchorage" + working_directory: ~/plotly.js + steps: + - run: sudo apt-get update + - browser-tools/install-browser-tools: + install-firefox: false + install-geckodriver: false + install-chrome: true + chrome-version: "132.0.6834.110" + - attach_workspace: + at: ~/ + - run: + name: Run performance tests + command: .circleci/test.sh performance-jasmine + + timezone-jasmine: docker: # need '-browsers' version to test in real (xvfb-wrapped) browsers @@ -500,6 +522,9 @@ workflows: - bundle-jasmine: requires: - install-and-cibuild + - performance-jasmine: + requires: + - install-and-cibuild - mathjax-firefoxLatest: requires: - install-and-cibuild diff --git a/.circleci/test.sh b/.circleci/test.sh index b814c1dd3e8..4df91e8af8c 100755 --- a/.circleci/test.sh +++ b/.circleci/test.sh @@ -79,6 +79,11 @@ case $1 in exit $EXIT_STATE ;; + performance-jasmine) + npm run test-performance || EXIT_STATE=$? + exit $EXIT_STATE + ;; + mathjax-firefox) ./node_modules/karma/bin/karma start test/jasmine/karma.conf.js --FF --bundleTest=mathjax --nowatch || EXIT_STATE=$? exit $EXIT_STATE diff --git a/package.json b/package.json index 39f76f1a5dd..94dd2045e0d 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "test-export": "node test/image/export_test.js", "test-syntax": "node tasks/test_syntax.js && npm run find-strings -- --no-output", "test-bundle": "node tasks/test_bundle.js", + "test-performance": "node tasks/test_performance.js", "test-plain-obj": "node tasks/test_plain_obj.mjs", "test": "npm run test-jasmine -- --nowatch && npm run test-bundle && npm run test-image && npm run test-export && npm run test-syntax && npm run lint", "b64": "python3 test/image/generate_b64_mocks.py && node devtools/test_dashboard/server.mjs", diff --git a/tasks/test_performance.js b/tasks/test_performance.js new file mode 100644 index 00000000000..1d1c9487536 --- /dev/null +++ b/tasks/test_performance.js @@ -0,0 +1,46 @@ +var path = require('path'); +var exec = require('child_process').exec; +var { glob } = require('glob'); +var runSeries = require('run-series'); + +var constants = require('./util/constants'); +var pathToJasminePerformanceTests = constants.pathToJasminePerformanceTests; + +/** + * Run all jasmine 'performance' test in series + * + * To run specific performance tests, use + * + * $ npm run test-jasmine -- --performanceTest= + */ +glob(pathToJasminePerformanceTests + '/*.js').then(function(files) { + var tasks = files.map(function(file) { + return function(cb) { + var cmd = [ + 'karma', 'start', + path.join(constants.pathToRoot, 'test', 'jasmine', 'karma.conf.js'), + '--performanceTest=' + path.basename(file), + '--nowatch' + ].join(' '); + + console.log('Running: ' + cmd); + + exec(cmd, function(err) { + cb(null, err); + }).stdout.pipe(process.stdout); + }; + }); + + runSeries(tasks, function(err, results) { + if(err) throw err; + + var failed = results.filter(function(r) { return r; }); + + if(failed.length) { + console.log('\ntest-performance summary:'); + failed.forEach(function(r) { console.warn('- ' + r.cmd + ' failed'); }); + console.log(''); + process.exit(1); + } + }); +}); diff --git a/tasks/util/constants.js b/tasks/util/constants.js index 6442501d9aa..69c1e88d64d 100644 --- a/tasks/util/constants.js +++ b/tasks/util/constants.js @@ -225,6 +225,7 @@ module.exports = { pathToJasmineTests: path.join(pathToRoot, 'test/jasmine/tests'), pathToJasmineBundleTests: path.join(pathToRoot, 'test/jasmine/bundle_tests'), + pathToJasminePerformanceTests: path.join(pathToRoot, 'test/jasmine/performance_tests'), // this mapbox access token is 'public', no need to hide it // more info: https://www.mapbox.com/help/define-access-token/ diff --git a/test/jasmine/karma.conf.js b/test/jasmine/karma.conf.js index f66235d7593..4653e346f44 100644 --- a/test/jasmine/karma.conf.js +++ b/test/jasmine/karma.conf.js @@ -8,7 +8,7 @@ var esbuildConfig = require('../../esbuild-config.js'); var isCI = Boolean(process.env.CI); var argv = minimist(process.argv.slice(4), { - string: ['bundleTest', 'width', 'height'], + string: ['bundleTest', 'performanceTest', 'width', 'height'], boolean: [ 'mathjax3', 'info', @@ -21,6 +21,7 @@ var argv = minimist(process.argv.slice(4), { Chrome: 'chrome', Firefox: ['firefox', 'FF'], bundleTest: ['bundletest', 'bundle_test'], + performanceTest: ['performancetest', 'performance_test'], nowatch: 'no-watch', failFast: 'fail-fast', }, @@ -53,7 +54,8 @@ if(argv.info) { ' - All non-flagged arguments corresponds to the test suites in `test/jasmine/tests/` to be run.', ' No need to add the `_test.js` suffix, we expand them correctly here.', ' - `--bundleTest` set the bundle test suite `test/jasmine/bundle_tests/ to be run.', - ' Note that only one bundle test can be run at a time.', + ' - `--performanceTest` set the bundle test suite `test/jasmine/performance_tests/ to be run.', + ' Note that only one bundle/performance test can be run at a time.', ' - Use `--tags` to specify which `@` tags to test (if any) e.g `npm run test-jasmine -- --tags=gl`', ' will run only gl tests.', ' - Use `--skip-tags` to specify which `@` tags to skip (if any) e.g `npm run test-jasmine -- --skip-tags=gl`', @@ -100,7 +102,8 @@ var glob = function(_) { }; var isBundleTest = !!argv.bundleTest; -var isFullSuite = !isBundleTest && argv._.length === 0; +var isPerformanceTest = !!argv.performanceTest; +var isFullSuite = !(isBundleTest || isPerformanceTest) && argv._.length === 0; var testFileGlob; if(isFullSuite) { @@ -113,6 +116,14 @@ if(isFullSuite) { } testFileGlob = path.join(__dirname, 'bundle_tests', glob([basename(_[0])])); +} else if(isPerformanceTest) { + var _ = merge(argv.performanceTest); + + if(_.length > 1) { + console.warn('Can only run one performance test suite at a time, ignoring ', _.slice(1)); + } + + testFileGlob = path.join(__dirname, 'performance_tests', glob([basename(_[0])])); } else { testFileGlob = path.join(__dirname, 'tests', glob(merge(argv._).map(basename))); } @@ -250,7 +261,7 @@ func.defaultConfig = { '--touch-events', '--window-size=' + argv.width + ',' + argv.height, isCI ? '--ignore-gpu-blacklist' : '', - (isBundleTest && basename(testFileGlob) === 'no_webgl') ? '--disable-webgl' : '' + ((isBundleTest || isPerformanceTest) && basename(testFileGlob) === 'no_webgl') ? '--disable-webgl' : '' ] }, _Firefox: { diff --git a/test/jasmine/performance_tests/bar_test.js b/test/jasmine/performance_tests/bar_test.js new file mode 100644 index 00000000000..8392bc0941c --- /dev/null +++ b/test/jasmine/performance_tests/bar_test.js @@ -0,0 +1,89 @@ +var createGraphDiv = require('../assets/create_graph_div'); +var delay = require('../assets/delay'); +var d3SelectAll = require('../../strict-d3').selectAll; +var Plotly = require('../../../lib/core'); +var PlotlyBar = require('../../../lib/bar'); + +var gd = createGraphDiv(); + +[{ + n: 1000, averageCap: 75 +}, { + n: 2000, averageCap: 100 +}, { + n: 4000, averageCap: 150 +}, { + n: 8000, averageCap: 300 +}, { + n: 16000, averageCap: 600 +}, { + n: 32000, averageCap: 1200 +}, { + n: 64000, averageCap: 2400 +}].forEach(function(spec) { + describe('Bundle with bar | size:' + spec.n, function() { + 'use strict'; + + Plotly.register(PlotlyBar); + + const samples = Array.from({ length: 5 }, (_, i) => i); + const nTimes = samples.length - 1; + + var y = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + + var mock = { + data: [{ + type: 'bar', + y: y + }], + layout: { + width: 1200, + height: 400 + } + }; + + var startTime; + + beforeEach(function(done) { + startTime = Date.now(); + + Plotly.newPlot(gd, mock).then(done); + }); + + afterEach(function(done) { + delay(100)().then(done); + }); + + var maxDelta = 0; + var aveDelta = 0; + + samples.forEach(function(t) { + it('should graph bar traces | turn: ' + t, function() { + var delta = Date.now() - startTime; + + if(t === 0) { + console.log('________________________________'); + console.log('number of points in bar: ' + spec.n); + console.log('expected average (cap): ' + spec.averageCap + ' ms'); + } + + if(t > 0) { // we skip the first run which is slow + maxDelta = Math.max(maxDelta, delta); + aveDelta += delta / nTimes; + } + + console.log('turn: ' + t + ' | ' + delta + ' ms'); + + if(t === nTimes) { + console.log('max: ' + maxDelta); + console.log('ave: ' + aveDelta); + + expect(aveDelta).toBeLessThan(spec.averageCap); + } + + var nodes = d3SelectAll('g.trace.bars'); + expect(nodes.size()).toEqual(1); + }); + }); + }); +}); diff --git a/test/jasmine/performance_tests/scatter_test.js b/test/jasmine/performance_tests/scatter_test.js new file mode 100644 index 00000000000..23634877680 --- /dev/null +++ b/test/jasmine/performance_tests/scatter_test.js @@ -0,0 +1,87 @@ +var createGraphDiv = require('../assets/create_graph_div'); +var delay = require('../assets/delay'); +var d3SelectAll = require('../../strict-d3').selectAll; +var Plotly = require('../../../lib/core'); + +var gd = createGraphDiv(); + +[{ + n: 1000, averageCap: 75 +}, { + n: 2000, averageCap: 100 +}, { + n: 4000, averageCap: 150 +}, { + n: 8000, averageCap: 300 +}, { + n: 16000, averageCap: 600 +}, { + n: 32000, averageCap: 1200 +}, { + n: 64000, averageCap: 2400 +}].forEach(function(spec) { + describe('Bundle with scatter | size:' + spec.n, function() { + 'use strict'; + + const samples = Array.from({ length: 5 }, (_, i) => i); + const nTimes = samples.length - 1; + + var y = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + + var mock = { + data: [{ + type: 'scatter', + mode: 'markers', + y: y + }], + layout: { + width: 1200, + height: 400 + } + }; + + var startTime; + + beforeEach(function(done) { + startTime = Date.now(); + + Plotly.newPlot(gd, mock).then(done); + }); + + afterEach(function(done) { + delay(100)().then(done); + }); + + var maxDelta = 0; + var aveDelta = 0; + + samples.forEach(function(t) { + it('should graph scatter traces | turn: ' + t, function() { + var delta = Date.now() - startTime; + + if(t === 0) { + console.log('________________________________'); + console.log('number of points in scatter: ' + spec.n); + console.log('expected average (cap): ' + spec.averageCap + ' ms'); + } + + if(t > 0) { // we skip the first run which is slow + maxDelta = Math.max(maxDelta, delta); + aveDelta += delta / nTimes; + } + + console.log('turn: ' + t + ' | ' + delta + ' ms'); + + if(t === nTimes) { + console.log('max: ' + maxDelta); + console.log('ave: ' + aveDelta); + + expect(aveDelta).toBeLessThan(spec.averageCap); + } + + var nodes = d3SelectAll('g.trace.scatter'); + expect(nodes.size()).toEqual(1); + }); + }); + }); +}); From 012abcabeb33155b292975ec9db9894be2d546c4 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Thu, 19 Jun 2025 09:39:10 -0400 Subject: [PATCH 02/46] collect performance data and create test report --- test/jasmine/performance_tests/bar_test.js | 34 +++-- test/jasmine/performance_tests/box_test.js | 102 +++++++++++++++ .../jasmine/performance_tests/contour_test.js | 112 +++++++++++++++++ .../jasmine/performance_tests/heatmap_test.js | 112 +++++++++++++++++ .../performance_tests/histogram_test.js | 101 +++++++++++++++ test/jasmine/performance_tests/image_test.js | 119 ++++++++++++++++++ .../jasmine/performance_tests/scatter_test.js | 34 +++-- 7 files changed, 592 insertions(+), 22 deletions(-) create mode 100644 test/jasmine/performance_tests/box_test.js create mode 100644 test/jasmine/performance_tests/contour_test.js create mode 100644 test/jasmine/performance_tests/heatmap_test.js create mode 100644 test/jasmine/performance_tests/histogram_test.js create mode 100644 test/jasmine/performance_tests/image_test.js diff --git a/test/jasmine/performance_tests/bar_test.js b/test/jasmine/performance_tests/bar_test.js index 8392bc0941c..4276c4c3840 100644 --- a/test/jasmine/performance_tests/bar_test.js +++ b/test/jasmine/performance_tests/bar_test.js @@ -6,7 +6,7 @@ var PlotlyBar = require('../../../lib/bar'); var gd = createGraphDiv(); -[{ +var tests = [{ n: 1000, averageCap: 75 }, { n: 2000, averageCap: 100 @@ -20,13 +20,15 @@ var gd = createGraphDiv(); n: 32000, averageCap: 1200 }, { n: 64000, averageCap: 2400 -}].forEach(function(spec) { - describe('Bundle with bar | size:' + spec.n, function() { +}]; + +tests.forEach(function(spec, index) { + describe('Performance test bar | size:' + spec.n, function() { 'use strict'; Plotly.register(PlotlyBar); - const samples = Array.from({ length: 5 }, (_, i) => i); + const samples = Array.from({ length: 9 }, (_, i) => i); const nTimes = samples.length - 1; var y = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); @@ -37,7 +39,7 @@ var gd = createGraphDiv(); y: y }], layout: { - width: 1200, + width: 900, height: 400 } }; @@ -62,27 +64,37 @@ var gd = createGraphDiv(); var delta = Date.now() - startTime; if(t === 0) { - console.log('________________________________'); - console.log('number of points in bar: ' + spec.n); - console.log('expected average (cap): ' + spec.averageCap + ' ms'); + // console.log('________________________________'); + // console.log('number of points: ' + spec.n); + // console.log('expected average (cap): ' + spec.averageCap + ' ms'); + + tests[index].raw = []; } + tests[index].raw[t] = delta; if(t > 0) { // we skip the first run which is slow maxDelta = Math.max(maxDelta, delta); aveDelta += delta / nTimes; } - console.log('turn: ' + t + ' | ' + delta + ' ms'); + // console.log('turn: ' + t + ' | ' + delta + ' ms'); if(t === nTimes) { - console.log('max: ' + maxDelta); - console.log('ave: ' + aveDelta); + tests[index].average = aveDelta; + tests[index].maximum = maxDelta; + + // console.log('max: ' + maxDelta); + // console.log('ave: ' + aveDelta); expect(aveDelta).toBeLessThan(spec.averageCap); } var nodes = d3SelectAll('g.trace.bars'); expect(nodes.size()).toEqual(1); + + if(t === nTimes && index === tests.length - 1) { + console.log(JSON.stringify(tests, null, 2)); + } }); }); }); diff --git a/test/jasmine/performance_tests/box_test.js b/test/jasmine/performance_tests/box_test.js new file mode 100644 index 00000000000..65e4ff374c0 --- /dev/null +++ b/test/jasmine/performance_tests/box_test.js @@ -0,0 +1,102 @@ +var createGraphDiv = require('../assets/create_graph_div'); +var delay = require('../assets/delay'); +var d3SelectAll = require('../../strict-d3').selectAll; +var Plotly = require('../../../lib/core'); +var PlotlyBox = require('../../../lib/box'); + +var gd = createGraphDiv(); + +var tests = [{ + n: 1000, averageCap: 75 +}, { + n: 2000, averageCap: 100 +}, { + n: 4000, averageCap: 150 +}, { + n: 8000, averageCap: 300 +}, { + n: 16000, averageCap: 600 +}, { + n: 32000, averageCap: 1200 +}, { + n: 64000, averageCap: 2400 +}]; + +tests.forEach(function(spec, index) { + describe('Performance test box | size:' + spec.n, function() { + 'use strict'; + + Plotly.register(PlotlyBox); + + const samples = Array.from({ length: 9 }, (_, i) => i); + const nTimes = samples.length - 1; + + var y = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + + var mock = { + data: [{ + type: 'box', + boxpoints: 'all', + y: y + }], + layout: { + width: 900, + height: 400 + } + }; + + var startTime; + + beforeEach(function(done) { + startTime = Date.now(); + + Plotly.newPlot(gd, mock).then(done); + }); + + afterEach(function(done) { + delay(100)().then(done); + }); + + var maxDelta = 0; + var aveDelta = 0; + + samples.forEach(function(t) { + it('should graph box traces | turn: ' + t, function() { + var delta = Date.now() - startTime; + + if(t === 0) { + // console.log('________________________________'); + // console.log('number of points: ' + spec.n); + // console.log('expected average (cap): ' + spec.averageCap + ' ms'); + + tests[index].raw = []; + } + tests[index].raw[t] = delta; + + if(t > 0) { // we skip the first run which is slow + maxDelta = Math.max(maxDelta, delta); + aveDelta += delta / nTimes; + } + + // console.log('turn: ' + t + ' | ' + delta + ' ms'); + + if(t === nTimes) { + tests[index].average = aveDelta; + tests[index].maximum = maxDelta; + + // console.log('max: ' + maxDelta); + // console.log('ave: ' + aveDelta); + + expect(aveDelta).toBeLessThan(spec.averageCap); + } + + var nodes = d3SelectAll('g.trace.boxes'); + expect(nodes.size()).toEqual(1); + + if(t === nTimes && index === tests.length - 1) { + console.log(JSON.stringify(tests, null, 2)); + } + }); + }); + }); +}); diff --git a/test/jasmine/performance_tests/contour_test.js b/test/jasmine/performance_tests/contour_test.js new file mode 100644 index 00000000000..00b4893fa62 --- /dev/null +++ b/test/jasmine/performance_tests/contour_test.js @@ -0,0 +1,112 @@ +var createGraphDiv = require('../assets/create_graph_div'); +var delay = require('../assets/delay'); +var d3SelectAll = require('../../strict-d3').selectAll; +var Plotly = require('../../../lib/core'); +var PlotlyContour = require('../../../lib/contour'); + +var gd = createGraphDiv(); + +var tests = [{ + nx: 50, ny: 20, averageCap: 100 +}, { + nx: 100, ny: 40, averageCap: 125 +}, { + nx: 200, ny: 80, averageCap: 250 +}, { + nx: 400, ny: 160, averageCap: 500 +}, { + nx: 800, ny: 320, averageCap: 1000 +}, { + nx: 1600, ny: 640, averageCap: 2000 +}, { + nx: 3200, ny: 1280, averageCap: 4000 +}]; + +tests.forEach(function(spec, index) { + describe('Performance test contour | size:' + spec.nx + 'X' + spec.ny, function() { + 'use strict'; + + Plotly.register(PlotlyContour); + + const samples = Array.from({ length: 9 }, (_, i) => i); + const nTimes = samples.length - 1; + + var A = spec.nx; + var B = spec.ny; + spec.n = A * B; + + var x = Uint16Array.from({ length: A }, (_, i) => i); + var y = Uint16Array.from({ length: B }, (_, i) => i); + var z = []; + for(var k = 0; k < B ; k++) { + z[k] = Float64Array.from({ length: A }, (_, i) => k * Math.cos(Math.sqrt(i))); + } + + var mock = { + data: [{ + type: 'contour', + x: x, + y: y, + z: z + }], + layout: { + width: 900, + height: 400 + } + }; + + var startTime; + + beforeEach(function(done) { + startTime = Date.now(); + + Plotly.newPlot(gd, mock).then(done); + }); + + afterEach(function(done) { + delay(100)().then(done); + }); + + var maxDelta = 0; + var aveDelta = 0; + + samples.forEach(function(t) { + it('should graph contour traces | turn: ' + t, function() { + var delta = Date.now() - startTime; + + if(t === 0) { + // console.log('________________________________'); + // console.log('number of points: ' + spec.n); + // console.log('expected average (cap): ' + spec.averageCap + ' ms'); + + tests[index].raw = []; + } + tests[index].raw[t] = delta; + + if(t > 0) { // we skip the first run which is slow + maxDelta = Math.max(maxDelta, delta); + aveDelta += delta / nTimes; + } + + // console.log('turn: ' + t + ' | ' + delta + ' ms'); + + if(t === nTimes) { + tests[index].average = aveDelta; + tests[index].maximum = maxDelta; + + // console.log('max: ' + maxDelta); + // console.log('ave: ' + aveDelta); + + expect(aveDelta).toBeLessThan(spec.averageCap); + } + + var nodes = d3SelectAll('g.contourlayer'); + expect(nodes.size()).toEqual(1); + + if(t === nTimes && index === tests.length - 1) { + console.log(JSON.stringify(tests, null, 2)); + } + }); + }); + }); +}); diff --git a/test/jasmine/performance_tests/heatmap_test.js b/test/jasmine/performance_tests/heatmap_test.js new file mode 100644 index 00000000000..454624bb716 --- /dev/null +++ b/test/jasmine/performance_tests/heatmap_test.js @@ -0,0 +1,112 @@ +var createGraphDiv = require('../assets/create_graph_div'); +var delay = require('../assets/delay'); +var d3SelectAll = require('../../strict-d3').selectAll; +var Plotly = require('../../../lib/core'); +var PlotlyHeatmap = require('../../../lib/heatmap'); + +var gd = createGraphDiv(); + +var tests = [{ + nx: 50, ny: 20, averageCap: 75 +}, { + nx: 100, ny: 40, averageCap: 100 +}, { + nx: 200, ny: 80, averageCap: 150 +}, { + nx: 400, ny: 160, averageCap: 300 +}, { + nx: 800, ny: 320, averageCap: 600 +}, { + nx: 1600, ny: 640, averageCap: 1200 +}, { + nx: 3200, ny: 1280, averageCap: 2400 +}]; + +tests.forEach(function(spec, index) { + describe('Performance test heatmap | size:' + spec.nx + 'X' + spec.ny, function() { + 'use strict'; + + Plotly.register(PlotlyHeatmap); + + const samples = Array.from({ length: 9 }, (_, i) => i); + const nTimes = samples.length - 1; + + var A = spec.nx; + var B = spec.ny; + spec.n = A * B; + + var x = Uint16Array.from({ length: A }, (_, i) => i); + var y = Uint16Array.from({ length: B }, (_, i) => i); + var z = []; + for(var k = 0; k < B ; k++) { + z[k] = Float64Array.from({ length: A }, (_, i) => k * Math.cos(Math.sqrt(i))); + } + + var mock = { + data: [{ + type: 'heatmap', + x: x, + y: y, + z: z + }], + layout: { + width: 900, + height: 400 + } + }; + + var startTime; + + beforeEach(function(done) { + startTime = Date.now(); + + Plotly.newPlot(gd, mock).then(done); + }); + + afterEach(function(done) { + delay(100)().then(done); + }); + + var maxDelta = 0; + var aveDelta = 0; + + samples.forEach(function(t) { + it('should graph heatmap traces | turn: ' + t, function() { + var delta = Date.now() - startTime; + + if(t === 0) { + // console.log('________________________________'); + // console.log('number of points: ' + spec.n); + // console.log('expected average (cap): ' + spec.averageCap + ' ms'); + + tests[index].raw = []; + } + tests[index].raw[t] = delta; + + if(t > 0) { // we skip the first run which is slow + maxDelta = Math.max(maxDelta, delta); + aveDelta += delta / nTimes; + } + + // console.log('turn: ' + t + ' | ' + delta + ' ms'); + + if(t === nTimes) { + tests[index].average = aveDelta; + tests[index].maximum = maxDelta; + + // console.log('max: ' + maxDelta); + // console.log('ave: ' + aveDelta); + + expect(aveDelta).toBeLessThan(spec.averageCap); + } + + var nodes = d3SelectAll('g.heatmaplayer'); + expect(nodes.size()).toEqual(1); + + if(t === nTimes && index === tests.length - 1) { + console.log(JSON.stringify(tests, null, 2)); + } + }); + }); + }); +}); diff --git a/test/jasmine/performance_tests/histogram_test.js b/test/jasmine/performance_tests/histogram_test.js new file mode 100644 index 00000000000..814c1f3c381 --- /dev/null +++ b/test/jasmine/performance_tests/histogram_test.js @@ -0,0 +1,101 @@ +var createGraphDiv = require('../assets/create_graph_div'); +var delay = require('../assets/delay'); +var d3SelectAll = require('../../strict-d3').selectAll; +var Plotly = require('../../../lib/core'); +var PlotlyHistogram = require('../../../lib/histogram'); + +var gd = createGraphDiv(); + +var tests = [{ + n: 1000, averageCap: 75 +}, { + n: 2000, averageCap: 100 +}, { + n: 4000, averageCap: 150 +}, { + n: 8000, averageCap: 300 +}, { + n: 16000, averageCap: 600 +}, { + n: 32000, averageCap: 1200 +}, { + n: 64000, averageCap: 2400 +}]; + +tests.forEach(function(spec, index) { + describe('Performance test histogram | size:' + spec.n, function() { + 'use strict'; + + Plotly.register(PlotlyHistogram); + + const samples = Array.from({ length: 9 }, (_, i) => i); + const nTimes = samples.length - 1; + + var x = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + + var mock = { + data: [{ + type: 'histogram', + x: x + }], + layout: { + width: 900, + height: 400 + } + }; + + var startTime; + + beforeEach(function(done) { + startTime = Date.now(); + + Plotly.newPlot(gd, mock).then(done); + }); + + afterEach(function(done) { + delay(100)().then(done); + }); + + var maxDelta = 0; + var aveDelta = 0; + + samples.forEach(function(t) { + it('should graph histogram traces | turn: ' + t, function() { + var delta = Date.now() - startTime; + + if(t === 0) { + // console.log('________________________________'); + // console.log('number of points: ' + spec.n); + // console.log('expected average (cap): ' + spec.averageCap + ' ms'); + + tests[index].raw = []; + } + tests[index].raw[t] = delta; + + if(t > 0) { // we skip the first run which is slow + maxDelta = Math.max(maxDelta, delta); + aveDelta += delta / nTimes; + } + + // console.log('turn: ' + t + ' | ' + delta + ' ms'); + + if(t === nTimes) { + tests[index].average = aveDelta; + tests[index].maximum = maxDelta; + + // console.log('max: ' + maxDelta); + // console.log('ave: ' + aveDelta); + + expect(aveDelta).toBeLessThan(spec.averageCap); + } + + var nodes = d3SelectAll('g.trace.bars'); + expect(nodes.size()).toEqual(1); + + if(t === nTimes && index === tests.length - 1) { + console.log(JSON.stringify(tests, null, 2)); + } + }); + }); + }); +}); diff --git a/test/jasmine/performance_tests/image_test.js b/test/jasmine/performance_tests/image_test.js new file mode 100644 index 00000000000..7e5a60eda72 --- /dev/null +++ b/test/jasmine/performance_tests/image_test.js @@ -0,0 +1,119 @@ +var createGraphDiv = require('../assets/create_graph_div'); +var delay = require('../assets/delay'); +var d3SelectAll = require('../../strict-d3').selectAll; +var Plotly = require('../../../lib/core'); +var PlotlyImage = require('../../../lib/image'); + +var gd = createGraphDiv(); + +var tests = [{ + nx: 50, ny: 20, averageCap: 75 +}, { + nx: 100, ny: 40, averageCap: 100 +}, { + nx: 200, ny: 80, averageCap: 150 +}, { + nx: 400, ny: 160, averageCap: 300 +}, { + nx: 800, ny: 320, averageCap: 600 +}, { + nx: 1600, ny: 640, averageCap: 1200 +}, { + nx: 3200, ny: 1280, averageCap: 2400 +}]; + +tests.forEach(function(spec, index) { + describe('Performance test image | size:' + spec.nx + 'X' + spec.ny, function() { + 'use strict'; + + Plotly.register(PlotlyImage); + + const samples = Array.from({ length: 9 }, (_, i) => i); + const nTimes = samples.length - 1; + + var A = spec.nx; + var B = spec.ny; + spec.n = A * B; + + var x = Uint16Array.from({ length: A }, (_, i) => i); + var y = Uint16Array.from({ length: B }, (_, i) => i); + var z = []; + for(var k = 0; k < B ; k++) { + z[k] = []; + for(var i = 0; i < A ; i++) { + z[k][i] = [ + Math.floor(127 * (1 + Math.cos(Math.sqrt(i)))), + 0, + Math.floor(127 * (1 + Math.cos(Math.sqrt(k)))), + ]; + } + } + + var mock = { + data: [{ + type: 'image', + x: x, + y: y, + z: z + }], + layout: { + width: 900, + height: 400 + } + }; + + var startTime; + + beforeEach(function(done) { + startTime = Date.now(); + + Plotly.newPlot(gd, mock).then(done); + }); + + afterEach(function(done) { + delay(100)().then(done); + }); + + var maxDelta = 0; + var aveDelta = 0; + + samples.forEach(function(t) { + it('should graph image traces | turn: ' + t, function() { + var delta = Date.now() - startTime; + + if(t === 0) { + // console.log('________________________________'); + // console.log('number of points: ' + spec.n); + // console.log('expected average (cap): ' + spec.averageCap + ' ms'); + + tests[index].raw = []; + } + tests[index].raw[t] = delta; + + if(t > 0) { // we skip the first run which is slow + maxDelta = Math.max(maxDelta, delta); + aveDelta += delta / nTimes; + } + + // console.log('turn: ' + t + ' | ' + delta + ' ms'); + + if(t === nTimes) { + tests[index].average = aveDelta; + tests[index].maximum = maxDelta; + + // console.log('max: ' + maxDelta); + // console.log('ave: ' + aveDelta); + + expect(aveDelta).toBeLessThan(spec.averageCap); + } + + var nodes = d3SelectAll('g.imagelayer.mlayer'); + expect(nodes.size()).toEqual(1); + + if(t === nTimes && index === tests.length - 1) { + console.log(JSON.stringify(tests, null, 2)); + } + }); + }); + }); +}); diff --git a/test/jasmine/performance_tests/scatter_test.js b/test/jasmine/performance_tests/scatter_test.js index 23634877680..741c134b75d 100644 --- a/test/jasmine/performance_tests/scatter_test.js +++ b/test/jasmine/performance_tests/scatter_test.js @@ -5,7 +5,7 @@ var Plotly = require('../../../lib/core'); var gd = createGraphDiv(); -[{ +var tests = [{ n: 1000, averageCap: 75 }, { n: 2000, averageCap: 100 @@ -19,11 +19,13 @@ var gd = createGraphDiv(); n: 32000, averageCap: 1200 }, { n: 64000, averageCap: 2400 -}].forEach(function(spec) { - describe('Bundle with scatter | size:' + spec.n, function() { +}]; + +tests.forEach(function(spec, index) { + describe('Performance test scatter | size:' + spec.n, function() { 'use strict'; - const samples = Array.from({ length: 5 }, (_, i) => i); + const samples = Array.from({ length: 9 }, (_, i) => i); const nTimes = samples.length - 1; var y = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); @@ -35,7 +37,7 @@ var gd = createGraphDiv(); y: y }], layout: { - width: 1200, + width: 900, height: 400 } }; @@ -60,27 +62,37 @@ var gd = createGraphDiv(); var delta = Date.now() - startTime; if(t === 0) { - console.log('________________________________'); - console.log('number of points in scatter: ' + spec.n); - console.log('expected average (cap): ' + spec.averageCap + ' ms'); + // console.log('________________________________'); + // console.log('number of points: ' + spec.n); + // console.log('expected average (cap): ' + spec.averageCap + ' ms'); + + tests[index].raw = []; } + tests[index].raw[t] = delta; if(t > 0) { // we skip the first run which is slow maxDelta = Math.max(maxDelta, delta); aveDelta += delta / nTimes; } - console.log('turn: ' + t + ' | ' + delta + ' ms'); + // console.log('turn: ' + t + ' | ' + delta + ' ms'); if(t === nTimes) { - console.log('max: ' + maxDelta); - console.log('ave: ' + aveDelta); + tests[index].average = aveDelta; + tests[index].maximum = maxDelta; + + // console.log('max: ' + maxDelta); + // console.log('ave: ' + aveDelta); expect(aveDelta).toBeLessThan(spec.averageCap); } var nodes = d3SelectAll('g.trace.scatter'); expect(nodes.size()).toEqual(1); + + if(t === nTimes && index === tests.length - 1) { + console.log(JSON.stringify(tests, null, 2)); + } }); }); }); From 0d9eb560d11000fb42c04b0413c77d29177c3f29 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Thu, 19 Jun 2025 18:57:02 -0400 Subject: [PATCH 03/46] skip testing against averageCap for now --- test/jasmine/performance_tests/bar_test.js | 2 +- test/jasmine/performance_tests/box_test.js | 2 +- test/jasmine/performance_tests/contour_test.js | 2 +- test/jasmine/performance_tests/heatmap_test.js | 2 +- test/jasmine/performance_tests/histogram_test.js | 2 +- test/jasmine/performance_tests/image_test.js | 2 +- test/jasmine/performance_tests/scatter_test.js | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/jasmine/performance_tests/bar_test.js b/test/jasmine/performance_tests/bar_test.js index 4276c4c3840..4e380917d86 100644 --- a/test/jasmine/performance_tests/bar_test.js +++ b/test/jasmine/performance_tests/bar_test.js @@ -86,7 +86,7 @@ tests.forEach(function(spec, index) { // console.log('max: ' + maxDelta); // console.log('ave: ' + aveDelta); - expect(aveDelta).toBeLessThan(spec.averageCap); + // expect(aveDelta).toBeLessThan(spec.averageCap); } var nodes = d3SelectAll('g.trace.bars'); diff --git a/test/jasmine/performance_tests/box_test.js b/test/jasmine/performance_tests/box_test.js index 65e4ff374c0..cdfd388c563 100644 --- a/test/jasmine/performance_tests/box_test.js +++ b/test/jasmine/performance_tests/box_test.js @@ -87,7 +87,7 @@ tests.forEach(function(spec, index) { // console.log('max: ' + maxDelta); // console.log('ave: ' + aveDelta); - expect(aveDelta).toBeLessThan(spec.averageCap); + // expect(aveDelta).toBeLessThan(spec.averageCap); } var nodes = d3SelectAll('g.trace.boxes'); diff --git a/test/jasmine/performance_tests/contour_test.js b/test/jasmine/performance_tests/contour_test.js index 00b4893fa62..d3d74e0085f 100644 --- a/test/jasmine/performance_tests/contour_test.js +++ b/test/jasmine/performance_tests/contour_test.js @@ -97,7 +97,7 @@ tests.forEach(function(spec, index) { // console.log('max: ' + maxDelta); // console.log('ave: ' + aveDelta); - expect(aveDelta).toBeLessThan(spec.averageCap); + // expect(aveDelta).toBeLessThan(spec.averageCap); } var nodes = d3SelectAll('g.contourlayer'); diff --git a/test/jasmine/performance_tests/heatmap_test.js b/test/jasmine/performance_tests/heatmap_test.js index 454624bb716..51499809359 100644 --- a/test/jasmine/performance_tests/heatmap_test.js +++ b/test/jasmine/performance_tests/heatmap_test.js @@ -97,7 +97,7 @@ tests.forEach(function(spec, index) { // console.log('max: ' + maxDelta); // console.log('ave: ' + aveDelta); - expect(aveDelta).toBeLessThan(spec.averageCap); + // expect(aveDelta).toBeLessThan(spec.averageCap); } var nodes = d3SelectAll('g.heatmaplayer'); diff --git a/test/jasmine/performance_tests/histogram_test.js b/test/jasmine/performance_tests/histogram_test.js index 814c1f3c381..9a1328e7ed1 100644 --- a/test/jasmine/performance_tests/histogram_test.js +++ b/test/jasmine/performance_tests/histogram_test.js @@ -86,7 +86,7 @@ tests.forEach(function(spec, index) { // console.log('max: ' + maxDelta); // console.log('ave: ' + aveDelta); - expect(aveDelta).toBeLessThan(spec.averageCap); + // expect(aveDelta).toBeLessThan(spec.averageCap); } var nodes = d3SelectAll('g.trace.bars'); diff --git a/test/jasmine/performance_tests/image_test.js b/test/jasmine/performance_tests/image_test.js index 7e5a60eda72..58ea002fd06 100644 --- a/test/jasmine/performance_tests/image_test.js +++ b/test/jasmine/performance_tests/image_test.js @@ -104,7 +104,7 @@ tests.forEach(function(spec, index) { // console.log('max: ' + maxDelta); // console.log('ave: ' + aveDelta); - expect(aveDelta).toBeLessThan(spec.averageCap); + // expect(aveDelta).toBeLessThan(spec.averageCap); } var nodes = d3SelectAll('g.imagelayer.mlayer'); diff --git a/test/jasmine/performance_tests/scatter_test.js b/test/jasmine/performance_tests/scatter_test.js index 741c134b75d..d81abe8b1a4 100644 --- a/test/jasmine/performance_tests/scatter_test.js +++ b/test/jasmine/performance_tests/scatter_test.js @@ -84,7 +84,7 @@ tests.forEach(function(spec, index) { // console.log('max: ' + maxDelta); // console.log('ave: ' + aveDelta); - expect(aveDelta).toBeLessThan(spec.averageCap); + // expect(aveDelta).toBeLessThan(spec.averageCap); } var nodes = d3SelectAll('g.trace.scatter'); From d7bf5b5bc0939edacdde33caa01107d872521cbd Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Thu, 19 Jun 2025 19:35:18 -0400 Subject: [PATCH 04/46] convert raw data to CSV --- .../performance_tests/assets/post_process.js | 15 +++++++++++++++ test/jasmine/performance_tests/bar_test.js | 3 +++ test/jasmine/performance_tests/box_test.js | 3 +++ test/jasmine/performance_tests/contour_test.js | 3 +++ test/jasmine/performance_tests/heatmap_test.js | 3 +++ test/jasmine/performance_tests/histogram_test.js | 3 +++ test/jasmine/performance_tests/image_test.js | 3 +++ test/jasmine/performance_tests/scatter_test.js | 3 +++ 8 files changed, 36 insertions(+) create mode 100644 test/jasmine/performance_tests/assets/post_process.js diff --git a/test/jasmine/performance_tests/assets/post_process.js b/test/jasmine/performance_tests/assets/post_process.js new file mode 100644 index 00000000000..1512632bb45 --- /dev/null +++ b/test/jasmine/performance_tests/assets/post_process.js @@ -0,0 +1,15 @@ +'use strict'; + +exports.writeRawDataAsCSV = function(traceName, allTests) { + for(var k = 0; k < allTests.length; k++) { + var test = allTests[k]; + + var str = traceName + ',' + test.n + '\n'; + str += 'id,time(ms)\n'; + for(var i = 0; i < test.raw.length; i++) { + str += i + ',' + test.raw[i] + '\n'; + } + + console.log(str); + } +}; diff --git a/test/jasmine/performance_tests/bar_test.js b/test/jasmine/performance_tests/bar_test.js index 4e380917d86..7be47841da7 100644 --- a/test/jasmine/performance_tests/bar_test.js +++ b/test/jasmine/performance_tests/bar_test.js @@ -3,6 +3,7 @@ var delay = require('../assets/delay'); var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyBar = require('../../../lib/bar'); +var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; var gd = createGraphDiv(); @@ -94,6 +95,8 @@ tests.forEach(function(spec, index) { if(t === nTimes && index === tests.length - 1) { console.log(JSON.stringify(tests, null, 2)); + + writeRawDataAsCSV('bar', tests); } }); }); diff --git a/test/jasmine/performance_tests/box_test.js b/test/jasmine/performance_tests/box_test.js index cdfd388c563..9bf10dbeb20 100644 --- a/test/jasmine/performance_tests/box_test.js +++ b/test/jasmine/performance_tests/box_test.js @@ -3,6 +3,7 @@ var delay = require('../assets/delay'); var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyBox = require('../../../lib/box'); +var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; var gd = createGraphDiv(); @@ -95,6 +96,8 @@ tests.forEach(function(spec, index) { if(t === nTimes && index === tests.length - 1) { console.log(JSON.stringify(tests, null, 2)); + + writeRawDataAsCSV('box', tests); } }); }); diff --git a/test/jasmine/performance_tests/contour_test.js b/test/jasmine/performance_tests/contour_test.js index d3d74e0085f..5e53db58938 100644 --- a/test/jasmine/performance_tests/contour_test.js +++ b/test/jasmine/performance_tests/contour_test.js @@ -3,6 +3,7 @@ var delay = require('../assets/delay'); var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyContour = require('../../../lib/contour'); +var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; var gd = createGraphDiv(); @@ -105,6 +106,8 @@ tests.forEach(function(spec, index) { if(t === nTimes && index === tests.length - 1) { console.log(JSON.stringify(tests, null, 2)); + + writeRawDataAsCSV('contour', tests); } }); }); diff --git a/test/jasmine/performance_tests/heatmap_test.js b/test/jasmine/performance_tests/heatmap_test.js index 51499809359..b23db01145d 100644 --- a/test/jasmine/performance_tests/heatmap_test.js +++ b/test/jasmine/performance_tests/heatmap_test.js @@ -3,6 +3,7 @@ var delay = require('../assets/delay'); var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyHeatmap = require('../../../lib/heatmap'); +var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; var gd = createGraphDiv(); @@ -105,6 +106,8 @@ tests.forEach(function(spec, index) { if(t === nTimes && index === tests.length - 1) { console.log(JSON.stringify(tests, null, 2)); + + writeRawDataAsCSV('heatmap', tests); } }); }); diff --git a/test/jasmine/performance_tests/histogram_test.js b/test/jasmine/performance_tests/histogram_test.js index 9a1328e7ed1..bc3c936645d 100644 --- a/test/jasmine/performance_tests/histogram_test.js +++ b/test/jasmine/performance_tests/histogram_test.js @@ -3,6 +3,7 @@ var delay = require('../assets/delay'); var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyHistogram = require('../../../lib/histogram'); +var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; var gd = createGraphDiv(); @@ -94,6 +95,8 @@ tests.forEach(function(spec, index) { if(t === nTimes && index === tests.length - 1) { console.log(JSON.stringify(tests, null, 2)); + + writeRawDataAsCSV('histogram', tests); } }); }); diff --git a/test/jasmine/performance_tests/image_test.js b/test/jasmine/performance_tests/image_test.js index 58ea002fd06..f388cebdcda 100644 --- a/test/jasmine/performance_tests/image_test.js +++ b/test/jasmine/performance_tests/image_test.js @@ -3,6 +3,7 @@ var delay = require('../assets/delay'); var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyImage = require('../../../lib/image'); +var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; var gd = createGraphDiv(); @@ -112,6 +113,8 @@ tests.forEach(function(spec, index) { if(t === nTimes && index === tests.length - 1) { console.log(JSON.stringify(tests, null, 2)); + + writeRawDataAsCSV('image', tests); } }); }); diff --git a/test/jasmine/performance_tests/scatter_test.js b/test/jasmine/performance_tests/scatter_test.js index d81abe8b1a4..8e73308766f 100644 --- a/test/jasmine/performance_tests/scatter_test.js +++ b/test/jasmine/performance_tests/scatter_test.js @@ -2,6 +2,7 @@ var createGraphDiv = require('../assets/create_graph_div'); var delay = require('../assets/delay'); var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); +var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; var gd = createGraphDiv(); @@ -92,6 +93,8 @@ tests.forEach(function(spec, index) { if(t === nTimes && index === tests.length - 1) { console.log(JSON.stringify(tests, null, 2)); + + writeRawDataAsCSV('scatter', tests); } }); }); From 9f607765cdd2fbe3a8d9e5cd9ae94745a7960244 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Fri, 20 Jun 2025 09:39:28 -0400 Subject: [PATCH 05/46] wait for actual rendering to complete --- test/jasmine/performance_tests/bar_test.js | 16 ++++++++++++---- test/jasmine/performance_tests/box_test.js | 16 ++++++++++++---- test/jasmine/performance_tests/contour_test.js | 16 ++++++++++++---- test/jasmine/performance_tests/heatmap_test.js | 16 ++++++++++++---- test/jasmine/performance_tests/histogram_test.js | 16 ++++++++++++---- test/jasmine/performance_tests/image_test.js | 16 ++++++++++++---- test/jasmine/performance_tests/scatter_test.js | 16 ++++++++++++---- 7 files changed, 84 insertions(+), 28 deletions(-) diff --git a/test/jasmine/performance_tests/bar_test.js b/test/jasmine/performance_tests/bar_test.js index 7be47841da7..4b6ac713e99 100644 --- a/test/jasmine/performance_tests/bar_test.js +++ b/test/jasmine/performance_tests/bar_test.js @@ -45,12 +45,20 @@ tests.forEach(function(spec, index) { } }; - var startTime; + var startTime, endTime; beforeEach(function(done) { - startTime = Date.now(); + startTime = performance.now(); + + // Wait for actual rendering to complete + requestAnimationFrame(function() { + requestAnimationFrame(function() { + endTime = performance.now(); + done(); + }); + }); - Plotly.newPlot(gd, mock).then(done); + Plotly.newPlot(gd, mock); }); afterEach(function(done) { @@ -62,7 +70,7 @@ tests.forEach(function(spec, index) { samples.forEach(function(t) { it('should graph bar traces | turn: ' + t, function() { - var delta = Date.now() - startTime; + var delta = endTime - startTime; if(t === 0) { // console.log('________________________________'); diff --git a/test/jasmine/performance_tests/box_test.js b/test/jasmine/performance_tests/box_test.js index 9bf10dbeb20..aa4d4d221dc 100644 --- a/test/jasmine/performance_tests/box_test.js +++ b/test/jasmine/performance_tests/box_test.js @@ -46,12 +46,20 @@ tests.forEach(function(spec, index) { } }; - var startTime; + var startTime, endTime; beforeEach(function(done) { - startTime = Date.now(); + startTime = performance.now(); + + // Wait for actual rendering to complete + requestAnimationFrame(function() { + requestAnimationFrame(function() { + endTime = performance.now(); + done(); + }); + }); - Plotly.newPlot(gd, mock).then(done); + Plotly.newPlot(gd, mock); }); afterEach(function(done) { @@ -63,7 +71,7 @@ tests.forEach(function(spec, index) { samples.forEach(function(t) { it('should graph box traces | turn: ' + t, function() { - var delta = Date.now() - startTime; + var delta = endTime - startTime; if(t === 0) { // console.log('________________________________'); diff --git a/test/jasmine/performance_tests/contour_test.js b/test/jasmine/performance_tests/contour_test.js index 5e53db58938..722a0d0d95d 100644 --- a/test/jasmine/performance_tests/contour_test.js +++ b/test/jasmine/performance_tests/contour_test.js @@ -56,12 +56,20 @@ tests.forEach(function(spec, index) { } }; - var startTime; + var startTime, endTime; beforeEach(function(done) { - startTime = Date.now(); + startTime = performance.now(); + + // Wait for actual rendering to complete + requestAnimationFrame(function() { + requestAnimationFrame(function() { + endTime = performance.now(); + done(); + }); + }); - Plotly.newPlot(gd, mock).then(done); + Plotly.newPlot(gd, mock); }); afterEach(function(done) { @@ -73,7 +81,7 @@ tests.forEach(function(spec, index) { samples.forEach(function(t) { it('should graph contour traces | turn: ' + t, function() { - var delta = Date.now() - startTime; + var delta = endTime - startTime; if(t === 0) { // console.log('________________________________'); diff --git a/test/jasmine/performance_tests/heatmap_test.js b/test/jasmine/performance_tests/heatmap_test.js index b23db01145d..fc9d01d5be9 100644 --- a/test/jasmine/performance_tests/heatmap_test.js +++ b/test/jasmine/performance_tests/heatmap_test.js @@ -56,12 +56,20 @@ tests.forEach(function(spec, index) { } }; - var startTime; + var startTime, endTime; beforeEach(function(done) { - startTime = Date.now(); + startTime = performance.now(); + + // Wait for actual rendering to complete + requestAnimationFrame(function() { + requestAnimationFrame(function() { + endTime = performance.now(); + done(); + }); + }); - Plotly.newPlot(gd, mock).then(done); + Plotly.newPlot(gd, mock); }); afterEach(function(done) { @@ -73,7 +81,7 @@ tests.forEach(function(spec, index) { samples.forEach(function(t) { it('should graph heatmap traces | turn: ' + t, function() { - var delta = Date.now() - startTime; + var delta = endTime - startTime; if(t === 0) { // console.log('________________________________'); diff --git a/test/jasmine/performance_tests/histogram_test.js b/test/jasmine/performance_tests/histogram_test.js index bc3c936645d..b95d80cd4ac 100644 --- a/test/jasmine/performance_tests/histogram_test.js +++ b/test/jasmine/performance_tests/histogram_test.js @@ -45,12 +45,20 @@ tests.forEach(function(spec, index) { } }; - var startTime; + var startTime, endTime; beforeEach(function(done) { - startTime = Date.now(); + startTime = performance.now(); + + // Wait for actual rendering to complete + requestAnimationFrame(function() { + requestAnimationFrame(function() { + endTime = performance.now(); + done(); + }); + }); - Plotly.newPlot(gd, mock).then(done); + Plotly.newPlot(gd, mock); }); afterEach(function(done) { @@ -62,7 +70,7 @@ tests.forEach(function(spec, index) { samples.forEach(function(t) { it('should graph histogram traces | turn: ' + t, function() { - var delta = Date.now() - startTime; + var delta = endTime - startTime; if(t === 0) { // console.log('________________________________'); diff --git a/test/jasmine/performance_tests/image_test.js b/test/jasmine/performance_tests/image_test.js index f388cebdcda..73a3d9ea020 100644 --- a/test/jasmine/performance_tests/image_test.js +++ b/test/jasmine/performance_tests/image_test.js @@ -63,12 +63,20 @@ tests.forEach(function(spec, index) { } }; - var startTime; + var startTime, endTime; beforeEach(function(done) { - startTime = Date.now(); + startTime = performance.now(); + + // Wait for actual rendering to complete + requestAnimationFrame(function() { + requestAnimationFrame(function() { + endTime = performance.now(); + done(); + }); + }); - Plotly.newPlot(gd, mock).then(done); + Plotly.newPlot(gd, mock); }); afterEach(function(done) { @@ -80,7 +88,7 @@ tests.forEach(function(spec, index) { samples.forEach(function(t) { it('should graph image traces | turn: ' + t, function() { - var delta = Date.now() - startTime; + var delta = endTime - startTime; if(t === 0) { // console.log('________________________________'); diff --git a/test/jasmine/performance_tests/scatter_test.js b/test/jasmine/performance_tests/scatter_test.js index 8e73308766f..a559b43b046 100644 --- a/test/jasmine/performance_tests/scatter_test.js +++ b/test/jasmine/performance_tests/scatter_test.js @@ -43,12 +43,20 @@ tests.forEach(function(spec, index) { } }; - var startTime; + var startTime, endTime; beforeEach(function(done) { - startTime = Date.now(); + startTime = performance.now(); + + // Wait for actual rendering to complete + requestAnimationFrame(function() { + requestAnimationFrame(function() { + endTime = performance.now(); + done(); + }); + }); - Plotly.newPlot(gd, mock).then(done); + Plotly.newPlot(gd, mock); }); afterEach(function(done) { @@ -60,7 +68,7 @@ tests.forEach(function(spec, index) { samples.forEach(function(t) { it('should graph scatter traces | turn: ' + t, function() { - var delta = Date.now() - startTime; + var delta = endTime - startTime; if(t === 0) { // console.log('________________________________'); From 12f73ad05098a32e8c2c8057fcc552ca7df84cc1 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Fri, 20 Jun 2025 10:38:13 -0400 Subject: [PATCH 06/46] download CSV file --- .../performance_tests/assets/post_process.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/test/jasmine/performance_tests/assets/post_process.js b/test/jasmine/performance_tests/assets/post_process.js index 1512632bb45..21dda96b62c 100644 --- a/test/jasmine/performance_tests/assets/post_process.js +++ b/test/jasmine/performance_tests/assets/post_process.js @@ -1,15 +1,27 @@ -'use strict'; - exports.writeRawDataAsCSV = function(traceName, allTests) { + var str = ''; for(var k = 0; k < allTests.length; k++) { var test = allTests[k]; - var str = traceName + ',' + test.n + '\n'; + str += traceName + ',' + test.n + '\n'; str += 'id,time(ms)\n'; for(var i = 0; i < test.raw.length; i++) { str += i + ',' + test.raw[i] + '\n'; } + str += '\n'; console.log(str); } + + // download a CSV file + var a = document.createElement('a'); + var myBlob = new Blob([str], {type: 'text/plain'}) + var url = window.URL.createObjectURL(myBlob); + a.href = url; + a.download = traceName + '.csv'; + a.style.display = 'none'; + document.body.append(a); + a.click(); + a.remove(); + window.URL.revokeObjectURL(url); }; From 2a4bc1ba9696e24a0eed44d390f8c7010e3e66f3 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Fri, 20 Jun 2025 11:24:11 -0400 Subject: [PATCH 07/46] revise CSV table --- test/jasmine/performance_tests/assets/post_process.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/test/jasmine/performance_tests/assets/post_process.js b/test/jasmine/performance_tests/assets/post_process.js index 21dda96b62c..898df5c8e94 100644 --- a/test/jasmine/performance_tests/assets/post_process.js +++ b/test/jasmine/performance_tests/assets/post_process.js @@ -1,18 +1,15 @@ exports.writeRawDataAsCSV = function(traceName, allTests) { - var str = ''; + var str = 'chart type,data points,run id,rendering time(ms)\n'; for(var k = 0; k < allTests.length; k++) { var test = allTests[k]; - str += traceName + ',' + test.n + '\n'; - str += 'id,time(ms)\n'; for(var i = 0; i < test.raw.length; i++) { - str += i + ',' + test.raw[i] + '\n'; + str += traceName + ',' + test.n + ',' + i + ',' + test.raw[i] + '\n'; } - str += '\n'; - - console.log(str); } + console.log(str); + // download a CSV file var a = document.createElement('a'); var myBlob = new Blob([str], {type: 'text/plain'}) From ba4327c38aa623a20b044eef2f9768ccbc4d54af Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Fri, 20 Jun 2025 11:26:59 -0400 Subject: [PATCH 08/46] store CSV --- .circleci/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6701dd7e259..6a1378f0800 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -53,6 +53,9 @@ jobs: - run: name: Run performance tests command: .circleci/test.sh performance-jasmine + - store_artifacts: + path: ~/Downloads + destination: / timezone-jasmine: From 855eaa2c82abb1ac60a397e9ff8b574cbab0e35f Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Fri, 20 Jun 2025 13:32:47 -0400 Subject: [PATCH 09/46] collect system info for performance tests --- .circleci/config.yml | 4 ++- package.json | 1 + tasks/system_info.js | 77 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 tasks/system_info.js diff --git a/.circleci/config.yml b/.circleci/config.yml index 6a1378f0800..d79afdb0d98 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -53,11 +53,13 @@ jobs: - run: name: Run performance tests command: .circleci/test.sh performance-jasmine + - run: + name: Display system information + command: npm run system-info > ~/Downloads/system_info.txt - store_artifacts: path: ~/Downloads destination: / - timezone-jasmine: docker: # need '-browsers' version to test in real (xvfb-wrapped) browsers diff --git a/package.json b/package.json index 94dd2045e0d..9d5930a4030 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "test-syntax": "node tasks/test_syntax.js && npm run find-strings -- --no-output", "test-bundle": "node tasks/test_bundle.js", "test-performance": "node tasks/test_performance.js", + "system-info": "node tasks/system_info.js", "test-plain-obj": "node tasks/test_plain_obj.mjs", "test": "npm run test-jasmine -- --nowatch && npm run test-bundle && npm run test-image && npm run test-export && npm run test-syntax && npm run lint", "b64": "python3 test/image/generate_b64_mocks.py && node devtools/test_dashboard/server.mjs", diff --git a/tasks/system_info.js b/tasks/system_info.js new file mode 100644 index 00000000000..fd09c670100 --- /dev/null +++ b/tasks/system_info.js @@ -0,0 +1,77 @@ +var os = require('os'); + +var logs = []; +function addLog(str) { + logs.push(str) +} + +var systemInfo = { + platform: os.platform(), + type: os.type(), + arch: os.arch(), + release: os.release(), + version: os.version ? os.version() : 'Unknown', + hostname: os.hostname(), + homedir: os.homedir(), + tmpdir: os.tmpdir(), + endianness: os.endianness(), +}; + +addLog('💻 SYSTEM:'); +addLog(` Platform: ${systemInfo.platform}`); +addLog(` Type: ${systemInfo.type}`); +addLog(` Architecture: ${systemInfo.arch}`); +addLog(` Release: ${systemInfo.release}`); +addLog(` Hostname: ${systemInfo.hostname}`); + + +var cpus = os.cpus(); +var loadAvg = os.loadavg(); + +var cpuInfo = { + model: cpus[0].model, + speed: cpus[0].speed, + cores: cpus.length, + loadAverage: loadAvg, + cpuDetails: cpus +}; + +addLog(''); +addLog('🔧 CPU:'); +addLog(` Model: ${cpuInfo.model}`); +addLog(` Speed: ${cpuInfo.speed} MHz`); +addLog(` Cores: ${cpuInfo.cores}${cpuInfo.physicalCores ? ` (${cpuInfo.physicalCores} physical)` : ''}`); +addLog(` Load Average: ${loadAvg.map(load => load.toFixed(2)).join(', ')}`); + + +var totalMem = os.totalmem(); +var freeMem = os.freemem(); +var usedMem = totalMem - freeMem; + +var memoryInfo = { + total: totalMem, + free: freeMem, + used: usedMem, + usagePercent: (usedMem / totalMem) * 100 +}; + +function formatBytes(bytes, decimals = 2) { + if (bytes === 0) return '0 Bytes'; + if (!bytes) return 'Unknown'; + + var k = 1024; + var dm = decimals < 0 ? 0 : decimals; + var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB']; + var i = Math.floor(Math.log(bytes) / Math.log(k)); + + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; +} + +addLog(''); +addLog('💾 MEMORY:'); +addLog(` Total: ${formatBytes(memoryInfo.total)}`); +addLog(` Used: ${formatBytes(memoryInfo.used)} (${memoryInfo.usagePercent.toFixed(1)}%)`); +addLog(` Free: ${formatBytes(memoryInfo.free)}`); + + +console.log(logs.join('\n')); \ No newline at end of file From c46e7c61d8ce60a7d3fc414a31a02008a60e017f Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 10:02:18 -0400 Subject: [PATCH 10/46] combine all csv files --- .circleci/config.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index d79afdb0d98..c1362c052e4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -53,6 +53,11 @@ jobs: - run: name: Run performance tests command: .circleci/test.sh performance-jasmine + - run: + name: Combine CSV files + command: | + head -n 1 `ls ~/Downloads/*.csv | head -n 1` > ~/Downloads/all.csv + tail -n+2 -q ~/Downloads/*.csv >> ~/Downloads/all.csv - run: name: Display system information command: npm run system-info > ~/Downloads/system_info.txt From 0e638144d376fe72abb88ccdfbd04c89c7f37382 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 10:06:14 -0400 Subject: [PATCH 11/46] do not display the JSON for now --- test/jasmine/performance_tests/bar_test.js | 2 +- test/jasmine/performance_tests/box_test.js | 2 +- test/jasmine/performance_tests/contour_test.js | 2 +- test/jasmine/performance_tests/heatmap_test.js | 2 +- test/jasmine/performance_tests/histogram_test.js | 2 +- test/jasmine/performance_tests/image_test.js | 2 +- test/jasmine/performance_tests/scatter_test.js | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/jasmine/performance_tests/bar_test.js b/test/jasmine/performance_tests/bar_test.js index 4b6ac713e99..486e2325596 100644 --- a/test/jasmine/performance_tests/bar_test.js +++ b/test/jasmine/performance_tests/bar_test.js @@ -102,7 +102,7 @@ tests.forEach(function(spec, index) { expect(nodes.size()).toEqual(1); if(t === nTimes && index === tests.length - 1) { - console.log(JSON.stringify(tests, null, 2)); + // console.log(JSON.stringify(tests, null, 2)); writeRawDataAsCSV('bar', tests); } diff --git a/test/jasmine/performance_tests/box_test.js b/test/jasmine/performance_tests/box_test.js index aa4d4d221dc..fe716b3d593 100644 --- a/test/jasmine/performance_tests/box_test.js +++ b/test/jasmine/performance_tests/box_test.js @@ -103,7 +103,7 @@ tests.forEach(function(spec, index) { expect(nodes.size()).toEqual(1); if(t === nTimes && index === tests.length - 1) { - console.log(JSON.stringify(tests, null, 2)); + // console.log(JSON.stringify(tests, null, 2)); writeRawDataAsCSV('box', tests); } diff --git a/test/jasmine/performance_tests/contour_test.js b/test/jasmine/performance_tests/contour_test.js index 722a0d0d95d..853ebc66c39 100644 --- a/test/jasmine/performance_tests/contour_test.js +++ b/test/jasmine/performance_tests/contour_test.js @@ -113,7 +113,7 @@ tests.forEach(function(spec, index) { expect(nodes.size()).toEqual(1); if(t === nTimes && index === tests.length - 1) { - console.log(JSON.stringify(tests, null, 2)); + // console.log(JSON.stringify(tests, null, 2)); writeRawDataAsCSV('contour', tests); } diff --git a/test/jasmine/performance_tests/heatmap_test.js b/test/jasmine/performance_tests/heatmap_test.js index fc9d01d5be9..dd3eae8d89b 100644 --- a/test/jasmine/performance_tests/heatmap_test.js +++ b/test/jasmine/performance_tests/heatmap_test.js @@ -113,7 +113,7 @@ tests.forEach(function(spec, index) { expect(nodes.size()).toEqual(1); if(t === nTimes && index === tests.length - 1) { - console.log(JSON.stringify(tests, null, 2)); + // console.log(JSON.stringify(tests, null, 2)); writeRawDataAsCSV('heatmap', tests); } diff --git a/test/jasmine/performance_tests/histogram_test.js b/test/jasmine/performance_tests/histogram_test.js index b95d80cd4ac..05e0ad96edd 100644 --- a/test/jasmine/performance_tests/histogram_test.js +++ b/test/jasmine/performance_tests/histogram_test.js @@ -102,7 +102,7 @@ tests.forEach(function(spec, index) { expect(nodes.size()).toEqual(1); if(t === nTimes && index === tests.length - 1) { - console.log(JSON.stringify(tests, null, 2)); + // console.log(JSON.stringify(tests, null, 2)); writeRawDataAsCSV('histogram', tests); } diff --git a/test/jasmine/performance_tests/image_test.js b/test/jasmine/performance_tests/image_test.js index 73a3d9ea020..73db9b89d58 100644 --- a/test/jasmine/performance_tests/image_test.js +++ b/test/jasmine/performance_tests/image_test.js @@ -120,7 +120,7 @@ tests.forEach(function(spec, index) { expect(nodes.size()).toEqual(1); if(t === nTimes && index === tests.length - 1) { - console.log(JSON.stringify(tests, null, 2)); + // console.log(JSON.stringify(tests, null, 2)); writeRawDataAsCSV('image', tests); } diff --git a/test/jasmine/performance_tests/scatter_test.js b/test/jasmine/performance_tests/scatter_test.js index a559b43b046..ec70e46ecc5 100644 --- a/test/jasmine/performance_tests/scatter_test.js +++ b/test/jasmine/performance_tests/scatter_test.js @@ -100,7 +100,7 @@ tests.forEach(function(spec, index) { expect(nodes.size()).toEqual(1); if(t === nTimes && index === tests.length - 1) { - console.log(JSON.stringify(tests, null, 2)); + // console.log(JSON.stringify(tests, null, 2)); writeRawDataAsCSV('scatter', tests); } From 5d2e5bb16432374dd177570ac90ec55e86679e29 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 10:15:18 -0400 Subject: [PATCH 12/46] simplify tests only keep raw results --- test/jasmine/performance_tests/bar_test.js | 40 ++++--------------- test/jasmine/performance_tests/box_test.js | 40 ++++--------------- .../jasmine/performance_tests/contour_test.js | 40 ++++--------------- .../jasmine/performance_tests/heatmap_test.js | 40 ++++--------------- .../performance_tests/histogram_test.js | 40 ++++--------------- test/jasmine/performance_tests/image_test.js | 40 ++++--------------- .../jasmine/performance_tests/scatter_test.js | 40 ++++--------------- 7 files changed, 49 insertions(+), 231 deletions(-) diff --git a/test/jasmine/performance_tests/bar_test.js b/test/jasmine/performance_tests/bar_test.js index 486e2325596..16d8a5a5b4b 100644 --- a/test/jasmine/performance_tests/bar_test.js +++ b/test/jasmine/performance_tests/bar_test.js @@ -8,19 +8,19 @@ var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; var gd = createGraphDiv(); var tests = [{ - n: 1000, averageCap: 75 + n: 1000 }, { - n: 2000, averageCap: 100 + n: 2000 }, { - n: 4000, averageCap: 150 + n: 4000 }, { - n: 8000, averageCap: 300 + n: 8000 }, { - n: 16000, averageCap: 600 + n: 16000 }, { - n: 32000, averageCap: 1200 + n: 32000 }, { - n: 64000, averageCap: 2400 + n: 64000 }]; tests.forEach(function(spec, index) { @@ -65,45 +65,19 @@ tests.forEach(function(spec, index) { delay(100)().then(done); }); - var maxDelta = 0; - var aveDelta = 0; - samples.forEach(function(t) { it('should graph bar traces | turn: ' + t, function() { var delta = endTime - startTime; if(t === 0) { - // console.log('________________________________'); - // console.log('number of points: ' + spec.n); - // console.log('expected average (cap): ' + spec.averageCap + ' ms'); - tests[index].raw = []; } tests[index].raw[t] = delta; - if(t > 0) { // we skip the first run which is slow - maxDelta = Math.max(maxDelta, delta); - aveDelta += delta / nTimes; - } - - // console.log('turn: ' + t + ' | ' + delta + ' ms'); - - if(t === nTimes) { - tests[index].average = aveDelta; - tests[index].maximum = maxDelta; - - // console.log('max: ' + maxDelta); - // console.log('ave: ' + aveDelta); - - // expect(aveDelta).toBeLessThan(spec.averageCap); - } - var nodes = d3SelectAll('g.trace.bars'); expect(nodes.size()).toEqual(1); if(t === nTimes && index === tests.length - 1) { - // console.log(JSON.stringify(tests, null, 2)); - writeRawDataAsCSV('bar', tests); } }); diff --git a/test/jasmine/performance_tests/box_test.js b/test/jasmine/performance_tests/box_test.js index fe716b3d593..2cfbf01f928 100644 --- a/test/jasmine/performance_tests/box_test.js +++ b/test/jasmine/performance_tests/box_test.js @@ -8,19 +8,19 @@ var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; var gd = createGraphDiv(); var tests = [{ - n: 1000, averageCap: 75 + n: 1000 }, { - n: 2000, averageCap: 100 + n: 2000 }, { - n: 4000, averageCap: 150 + n: 4000 }, { - n: 8000, averageCap: 300 + n: 8000 }, { - n: 16000, averageCap: 600 + n: 16000 }, { - n: 32000, averageCap: 1200 + n: 32000 }, { - n: 64000, averageCap: 2400 + n: 64000 }]; tests.forEach(function(spec, index) { @@ -66,45 +66,19 @@ tests.forEach(function(spec, index) { delay(100)().then(done); }); - var maxDelta = 0; - var aveDelta = 0; - samples.forEach(function(t) { it('should graph box traces | turn: ' + t, function() { var delta = endTime - startTime; if(t === 0) { - // console.log('________________________________'); - // console.log('number of points: ' + spec.n); - // console.log('expected average (cap): ' + spec.averageCap + ' ms'); - tests[index].raw = []; } tests[index].raw[t] = delta; - if(t > 0) { // we skip the first run which is slow - maxDelta = Math.max(maxDelta, delta); - aveDelta += delta / nTimes; - } - - // console.log('turn: ' + t + ' | ' + delta + ' ms'); - - if(t === nTimes) { - tests[index].average = aveDelta; - tests[index].maximum = maxDelta; - - // console.log('max: ' + maxDelta); - // console.log('ave: ' + aveDelta); - - // expect(aveDelta).toBeLessThan(spec.averageCap); - } - var nodes = d3SelectAll('g.trace.boxes'); expect(nodes.size()).toEqual(1); if(t === nTimes && index === tests.length - 1) { - // console.log(JSON.stringify(tests, null, 2)); - writeRawDataAsCSV('box', tests); } }); diff --git a/test/jasmine/performance_tests/contour_test.js b/test/jasmine/performance_tests/contour_test.js index 853ebc66c39..b3a564320df 100644 --- a/test/jasmine/performance_tests/contour_test.js +++ b/test/jasmine/performance_tests/contour_test.js @@ -8,19 +8,19 @@ var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; var gd = createGraphDiv(); var tests = [{ - nx: 50, ny: 20, averageCap: 100 + nx: 50, ny: 20 }, { - nx: 100, ny: 40, averageCap: 125 + nx: 100, ny: 40 }, { - nx: 200, ny: 80, averageCap: 250 + nx: 200, ny: 80 }, { - nx: 400, ny: 160, averageCap: 500 + nx: 400, ny: 160 }, { - nx: 800, ny: 320, averageCap: 1000 + nx: 800, ny: 320 }, { - nx: 1600, ny: 640, averageCap: 2000 + nx: 1600, ny: 640 }, { - nx: 3200, ny: 1280, averageCap: 4000 + nx: 3200, ny: 1280 }]; tests.forEach(function(spec, index) { @@ -76,45 +76,19 @@ tests.forEach(function(spec, index) { delay(100)().then(done); }); - var maxDelta = 0; - var aveDelta = 0; - samples.forEach(function(t) { it('should graph contour traces | turn: ' + t, function() { var delta = endTime - startTime; if(t === 0) { - // console.log('________________________________'); - // console.log('number of points: ' + spec.n); - // console.log('expected average (cap): ' + spec.averageCap + ' ms'); - tests[index].raw = []; } tests[index].raw[t] = delta; - if(t > 0) { // we skip the first run which is slow - maxDelta = Math.max(maxDelta, delta); - aveDelta += delta / nTimes; - } - - // console.log('turn: ' + t + ' | ' + delta + ' ms'); - - if(t === nTimes) { - tests[index].average = aveDelta; - tests[index].maximum = maxDelta; - - // console.log('max: ' + maxDelta); - // console.log('ave: ' + aveDelta); - - // expect(aveDelta).toBeLessThan(spec.averageCap); - } - var nodes = d3SelectAll('g.contourlayer'); expect(nodes.size()).toEqual(1); if(t === nTimes && index === tests.length - 1) { - // console.log(JSON.stringify(tests, null, 2)); - writeRawDataAsCSV('contour', tests); } }); diff --git a/test/jasmine/performance_tests/heatmap_test.js b/test/jasmine/performance_tests/heatmap_test.js index dd3eae8d89b..e670025566e 100644 --- a/test/jasmine/performance_tests/heatmap_test.js +++ b/test/jasmine/performance_tests/heatmap_test.js @@ -8,19 +8,19 @@ var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; var gd = createGraphDiv(); var tests = [{ - nx: 50, ny: 20, averageCap: 75 + nx: 50, ny: 20 }, { - nx: 100, ny: 40, averageCap: 100 + nx: 100, ny: 40 }, { - nx: 200, ny: 80, averageCap: 150 + nx: 200, ny: 80 }, { - nx: 400, ny: 160, averageCap: 300 + nx: 400, ny: 160 }, { - nx: 800, ny: 320, averageCap: 600 + nx: 800, ny: 320 }, { - nx: 1600, ny: 640, averageCap: 1200 + nx: 1600, ny: 640 }, { - nx: 3200, ny: 1280, averageCap: 2400 + nx: 3200, ny: 1280 }]; tests.forEach(function(spec, index) { @@ -76,45 +76,19 @@ tests.forEach(function(spec, index) { delay(100)().then(done); }); - var maxDelta = 0; - var aveDelta = 0; - samples.forEach(function(t) { it('should graph heatmap traces | turn: ' + t, function() { var delta = endTime - startTime; if(t === 0) { - // console.log('________________________________'); - // console.log('number of points: ' + spec.n); - // console.log('expected average (cap): ' + spec.averageCap + ' ms'); - tests[index].raw = []; } tests[index].raw[t] = delta; - if(t > 0) { // we skip the first run which is slow - maxDelta = Math.max(maxDelta, delta); - aveDelta += delta / nTimes; - } - - // console.log('turn: ' + t + ' | ' + delta + ' ms'); - - if(t === nTimes) { - tests[index].average = aveDelta; - tests[index].maximum = maxDelta; - - // console.log('max: ' + maxDelta); - // console.log('ave: ' + aveDelta); - - // expect(aveDelta).toBeLessThan(spec.averageCap); - } - var nodes = d3SelectAll('g.heatmaplayer'); expect(nodes.size()).toEqual(1); if(t === nTimes && index === tests.length - 1) { - // console.log(JSON.stringify(tests, null, 2)); - writeRawDataAsCSV('heatmap', tests); } }); diff --git a/test/jasmine/performance_tests/histogram_test.js b/test/jasmine/performance_tests/histogram_test.js index 05e0ad96edd..0ea1ad1ab33 100644 --- a/test/jasmine/performance_tests/histogram_test.js +++ b/test/jasmine/performance_tests/histogram_test.js @@ -8,19 +8,19 @@ var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; var gd = createGraphDiv(); var tests = [{ - n: 1000, averageCap: 75 + n: 1000 }, { - n: 2000, averageCap: 100 + n: 2000 }, { - n: 4000, averageCap: 150 + n: 4000 }, { - n: 8000, averageCap: 300 + n: 8000 }, { - n: 16000, averageCap: 600 + n: 16000 }, { - n: 32000, averageCap: 1200 + n: 32000 }, { - n: 64000, averageCap: 2400 + n: 64000 }]; tests.forEach(function(spec, index) { @@ -65,45 +65,19 @@ tests.forEach(function(spec, index) { delay(100)().then(done); }); - var maxDelta = 0; - var aveDelta = 0; - samples.forEach(function(t) { it('should graph histogram traces | turn: ' + t, function() { var delta = endTime - startTime; if(t === 0) { - // console.log('________________________________'); - // console.log('number of points: ' + spec.n); - // console.log('expected average (cap): ' + spec.averageCap + ' ms'); - tests[index].raw = []; } tests[index].raw[t] = delta; - if(t > 0) { // we skip the first run which is slow - maxDelta = Math.max(maxDelta, delta); - aveDelta += delta / nTimes; - } - - // console.log('turn: ' + t + ' | ' + delta + ' ms'); - - if(t === nTimes) { - tests[index].average = aveDelta; - tests[index].maximum = maxDelta; - - // console.log('max: ' + maxDelta); - // console.log('ave: ' + aveDelta); - - // expect(aveDelta).toBeLessThan(spec.averageCap); - } - var nodes = d3SelectAll('g.trace.bars'); expect(nodes.size()).toEqual(1); if(t === nTimes && index === tests.length - 1) { - // console.log(JSON.stringify(tests, null, 2)); - writeRawDataAsCSV('histogram', tests); } }); diff --git a/test/jasmine/performance_tests/image_test.js b/test/jasmine/performance_tests/image_test.js index 73db9b89d58..456b65e4bfd 100644 --- a/test/jasmine/performance_tests/image_test.js +++ b/test/jasmine/performance_tests/image_test.js @@ -8,19 +8,19 @@ var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; var gd = createGraphDiv(); var tests = [{ - nx: 50, ny: 20, averageCap: 75 + nx: 50, ny: 20 }, { - nx: 100, ny: 40, averageCap: 100 + nx: 100, ny: 40 }, { - nx: 200, ny: 80, averageCap: 150 + nx: 200, ny: 80 }, { - nx: 400, ny: 160, averageCap: 300 + nx: 400, ny: 160 }, { - nx: 800, ny: 320, averageCap: 600 + nx: 800, ny: 320 }, { - nx: 1600, ny: 640, averageCap: 1200 + nx: 1600, ny: 640 }, { - nx: 3200, ny: 1280, averageCap: 2400 + nx: 3200, ny: 1280 }]; tests.forEach(function(spec, index) { @@ -83,45 +83,19 @@ tests.forEach(function(spec, index) { delay(100)().then(done); }); - var maxDelta = 0; - var aveDelta = 0; - samples.forEach(function(t) { it('should graph image traces | turn: ' + t, function() { var delta = endTime - startTime; if(t === 0) { - // console.log('________________________________'); - // console.log('number of points: ' + spec.n); - // console.log('expected average (cap): ' + spec.averageCap + ' ms'); - tests[index].raw = []; } tests[index].raw[t] = delta; - if(t > 0) { // we skip the first run which is slow - maxDelta = Math.max(maxDelta, delta); - aveDelta += delta / nTimes; - } - - // console.log('turn: ' + t + ' | ' + delta + ' ms'); - - if(t === nTimes) { - tests[index].average = aveDelta; - tests[index].maximum = maxDelta; - - // console.log('max: ' + maxDelta); - // console.log('ave: ' + aveDelta); - - // expect(aveDelta).toBeLessThan(spec.averageCap); - } - var nodes = d3SelectAll('g.imagelayer.mlayer'); expect(nodes.size()).toEqual(1); if(t === nTimes && index === tests.length - 1) { - // console.log(JSON.stringify(tests, null, 2)); - writeRawDataAsCSV('image', tests); } }); diff --git a/test/jasmine/performance_tests/scatter_test.js b/test/jasmine/performance_tests/scatter_test.js index ec70e46ecc5..126ce3378dd 100644 --- a/test/jasmine/performance_tests/scatter_test.js +++ b/test/jasmine/performance_tests/scatter_test.js @@ -7,19 +7,19 @@ var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; var gd = createGraphDiv(); var tests = [{ - n: 1000, averageCap: 75 + n: 1000 }, { - n: 2000, averageCap: 100 + n: 2000 }, { - n: 4000, averageCap: 150 + n: 4000 }, { - n: 8000, averageCap: 300 + n: 8000 }, { - n: 16000, averageCap: 600 + n: 16000 }, { - n: 32000, averageCap: 1200 + n: 32000 }, { - n: 64000, averageCap: 2400 + n: 64000 }]; tests.forEach(function(spec, index) { @@ -63,45 +63,19 @@ tests.forEach(function(spec, index) { delay(100)().then(done); }); - var maxDelta = 0; - var aveDelta = 0; - samples.forEach(function(t) { it('should graph scatter traces | turn: ' + t, function() { var delta = endTime - startTime; if(t === 0) { - // console.log('________________________________'); - // console.log('number of points: ' + spec.n); - // console.log('expected average (cap): ' + spec.averageCap + ' ms'); - tests[index].raw = []; } tests[index].raw[t] = delta; - if(t > 0) { // we skip the first run which is slow - maxDelta = Math.max(maxDelta, delta); - aveDelta += delta / nTimes; - } - - // console.log('turn: ' + t + ' | ' + delta + ' ms'); - - if(t === nTimes) { - tests[index].average = aveDelta; - tests[index].maximum = maxDelta; - - // console.log('max: ' + maxDelta); - // console.log('ave: ' + aveDelta); - - // expect(aveDelta).toBeLessThan(spec.averageCap); - } - var nodes = d3SelectAll('g.trace.scatter'); expect(nodes.size()).toEqual(1); if(t === nTimes && index === tests.length - 1) { - // console.log(JSON.stringify(tests, null, 2)); - writeRawDataAsCSV('scatter', tests); } }); From 94b2fe039a2636d3db145eba2f1b37b03693b191 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 10:53:48 -0400 Subject: [PATCH 13/46] add violin tests --- test/jasmine/performance_tests/violin_test.js | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 test/jasmine/performance_tests/violin_test.js diff --git a/test/jasmine/performance_tests/violin_test.js b/test/jasmine/performance_tests/violin_test.js new file mode 100644 index 00000000000..bd8e7c11602 --- /dev/null +++ b/test/jasmine/performance_tests/violin_test.js @@ -0,0 +1,87 @@ +var createGraphDiv = require('../assets/create_graph_div'); +var delay = require('../assets/delay'); +var d3SelectAll = require('../../strict-d3').selectAll; +var Plotly = require('../../../lib/core'); +var PlotlyViolin = require('../../../lib/violin'); +var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; + +var gd = createGraphDiv(); + +var tests = [{ + n: 1000 +}, { + n: 2000 +}, { + n: 4000 +}, { + n: 8000 +}, { + n: 16000 +}, { + n: 32000 +}, { + n: 64000 +}]; + +tests.forEach(function(spec, index) { + describe('Performance test violin | size:' + spec.n, function() { + 'use strict'; + + Plotly.register(PlotlyViolin); + + const samples = Array.from({ length: 9 }, (_, i) => i); + const nTimes = samples.length - 1; + + var y = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + + var mock = { + data: [{ + type: 'violin', + points: 'all', + y: y + }], + layout: { + width: 900, + height: 400 + } + }; + + var startTime, endTime; + + beforeEach(function(done) { + startTime = performance.now(); + + // Wait for actual rendering to complete + requestAnimationFrame(function() { + requestAnimationFrame(function() { + endTime = performance.now(); + done(); + }); + }); + + Plotly.newPlot(gd, mock); + }); + + afterEach(function(done) { + delay(100)().then(done); + }); + + samples.forEach(function(t) { + it('should graph violin traces | turn: ' + t, function() { + var delta = endTime - startTime; + + if(t === 0) { + tests[index].raw = []; + } + tests[index].raw[t] = delta; + + var nodes = d3SelectAll('g.trace.violins'); + expect(nodes.size()).toEqual(1); + + if(t === nTimes && index === tests.length - 1) { + writeRawDataAsCSV('violin', tests); + } + }); + }); + }); +}); From b532cb0457118dbda673fb5dd9c5d4174e58403f Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 11:03:07 -0400 Subject: [PATCH 14/46] add scattergl tests --- .../performance_tests/scattergl_test.js | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 test/jasmine/performance_tests/scattergl_test.js diff --git a/test/jasmine/performance_tests/scattergl_test.js b/test/jasmine/performance_tests/scattergl_test.js new file mode 100644 index 00000000000..fd899919a9b --- /dev/null +++ b/test/jasmine/performance_tests/scattergl_test.js @@ -0,0 +1,91 @@ +var createGraphDiv = require('../assets/create_graph_div'); +var delay = require('../assets/delay'); +var Plotly = require('../../../lib/core'); +var PlotlyScattergl = require('../../../lib/scattergl'); +var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; + +var gd = createGraphDiv(); + +var tests = [{ + n: 1000 +}, { + n: 2000 +}, { + n: 4000 +}, { + n: 8000 +}, { + n: 16000 +}, { + n: 32000 +}, { + n: 64000 +}, { + n: 128000 +}, { + n: 256000 +}, { + n: 512000 +}, { + n: 1024000 +}]; + +tests.forEach(function(spec, index) { + describe('Performance test scattergl | size:' + spec.n, function() { + 'use strict'; + + Plotly.register(PlotlyScattergl); + + const samples = Array.from({ length: 9 }, (_, i) => i); + const nTimes = samples.length - 1; + + var y = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + + var mock = { + data: [{ + type: 'scattergl', + mode: 'markers', + y: y + }], + layout: { + width: 900, + height: 400 + } + }; + + var startTime, endTime; + + beforeEach(function(done) { + startTime = performance.now(); + + // Wait for actual rendering to complete + requestAnimationFrame(function() { + requestAnimationFrame(function() { + endTime = performance.now(); + done(); + }); + }); + + Plotly.newPlot(gd, mock); + }); + + afterEach(function(done) { + delay(100)().then(done); + }); + + samples.forEach(function(t) { + it('should graph scattergl traces | turn: ' + t, function() { + var delta = endTime - startTime; + + if(t === 0) { + tests[index].raw = []; + } + tests[index].raw[t] = delta; + + if(t === nTimes && index === tests.length - 1) { + writeRawDataAsCSV('scattergl', tests); + } + }); + }); + }); +}); From ef345ef055e9a6fa2477f59cedc8fe0d557e6a27 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 11:19:02 -0400 Subject: [PATCH 15/46] refactor tests --- test/jasmine/performance_tests/bar_test.js | 10 +++++----- test/jasmine/performance_tests/box_test.js | 10 +++++----- test/jasmine/performance_tests/contour_test.js | 10 +++++----- test/jasmine/performance_tests/heatmap_test.js | 10 +++++----- test/jasmine/performance_tests/histogram_test.js | 10 +++++----- test/jasmine/performance_tests/image_test.js | 7 +++++-- test/jasmine/performance_tests/scatter_test.js | 6 +++--- test/jasmine/performance_tests/scattergl_test.js | 10 +++++----- test/jasmine/performance_tests/violin_test.js | 10 +++++----- 9 files changed, 43 insertions(+), 40 deletions(-) diff --git a/test/jasmine/performance_tests/bar_test.js b/test/jasmine/performance_tests/bar_test.js index 16d8a5a5b4b..d455357f6c4 100644 --- a/test/jasmine/performance_tests/bar_test.js +++ b/test/jasmine/performance_tests/bar_test.js @@ -5,8 +5,13 @@ var Plotly = require('../../../lib/core'); var PlotlyBar = require('../../../lib/bar'); var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +Plotly.register(PlotlyBar); + var gd = createGraphDiv(); +const samples = Array.from({ length: 9 }, (_, i) => i); +const nTimes = samples.length - 1; + var tests = [{ n: 1000 }, { @@ -27,11 +32,6 @@ tests.forEach(function(spec, index) { describe('Performance test bar | size:' + spec.n, function() { 'use strict'; - Plotly.register(PlotlyBar); - - const samples = Array.from({ length: 9 }, (_, i) => i); - const nTimes = samples.length - 1; - var y = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); var mock = { diff --git a/test/jasmine/performance_tests/box_test.js b/test/jasmine/performance_tests/box_test.js index 2cfbf01f928..6caf60b5afe 100644 --- a/test/jasmine/performance_tests/box_test.js +++ b/test/jasmine/performance_tests/box_test.js @@ -5,8 +5,13 @@ var Plotly = require('../../../lib/core'); var PlotlyBox = require('../../../lib/box'); var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +Plotly.register(PlotlyBox); + var gd = createGraphDiv(); +const samples = Array.from({ length: 9 }, (_, i) => i); +const nTimes = samples.length - 1; + var tests = [{ n: 1000 }, { @@ -27,11 +32,6 @@ tests.forEach(function(spec, index) { describe('Performance test box | size:' + spec.n, function() { 'use strict'; - Plotly.register(PlotlyBox); - - const samples = Array.from({ length: 9 }, (_, i) => i); - const nTimes = samples.length - 1; - var y = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); var mock = { diff --git a/test/jasmine/performance_tests/contour_test.js b/test/jasmine/performance_tests/contour_test.js index b3a564320df..3a7cff40f8f 100644 --- a/test/jasmine/performance_tests/contour_test.js +++ b/test/jasmine/performance_tests/contour_test.js @@ -5,8 +5,13 @@ var Plotly = require('../../../lib/core'); var PlotlyContour = require('../../../lib/contour'); var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +Plotly.register(PlotlyContour); + var gd = createGraphDiv(); +const samples = Array.from({ length: 9 }, (_, i) => i); +const nTimes = samples.length - 1; + var tests = [{ nx: 50, ny: 20 }, { @@ -27,11 +32,6 @@ tests.forEach(function(spec, index) { describe('Performance test contour | size:' + spec.nx + 'X' + spec.ny, function() { 'use strict'; - Plotly.register(PlotlyContour); - - const samples = Array.from({ length: 9 }, (_, i) => i); - const nTimes = samples.length - 1; - var A = spec.nx; var B = spec.ny; spec.n = A * B; diff --git a/test/jasmine/performance_tests/heatmap_test.js b/test/jasmine/performance_tests/heatmap_test.js index e670025566e..a28a7d19455 100644 --- a/test/jasmine/performance_tests/heatmap_test.js +++ b/test/jasmine/performance_tests/heatmap_test.js @@ -5,8 +5,13 @@ var Plotly = require('../../../lib/core'); var PlotlyHeatmap = require('../../../lib/heatmap'); var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +Plotly.register(PlotlyHeatmap); + var gd = createGraphDiv(); +const samples = Array.from({ length: 9 }, (_, i) => i); +const nTimes = samples.length - 1; + var tests = [{ nx: 50, ny: 20 }, { @@ -27,11 +32,6 @@ tests.forEach(function(spec, index) { describe('Performance test heatmap | size:' + spec.nx + 'X' + spec.ny, function() { 'use strict'; - Plotly.register(PlotlyHeatmap); - - const samples = Array.from({ length: 9 }, (_, i) => i); - const nTimes = samples.length - 1; - var A = spec.nx; var B = spec.ny; spec.n = A * B; diff --git a/test/jasmine/performance_tests/histogram_test.js b/test/jasmine/performance_tests/histogram_test.js index 0ea1ad1ab33..0685187e813 100644 --- a/test/jasmine/performance_tests/histogram_test.js +++ b/test/jasmine/performance_tests/histogram_test.js @@ -5,8 +5,13 @@ var Plotly = require('../../../lib/core'); var PlotlyHistogram = require('../../../lib/histogram'); var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +Plotly.register(PlotlyHistogram); + var gd = createGraphDiv(); +const samples = Array.from({ length: 9 }, (_, i) => i); +const nTimes = samples.length - 1; + var tests = [{ n: 1000 }, { @@ -27,11 +32,6 @@ tests.forEach(function(spec, index) { describe('Performance test histogram | size:' + spec.n, function() { 'use strict'; - Plotly.register(PlotlyHistogram); - - const samples = Array.from({ length: 9 }, (_, i) => i); - const nTimes = samples.length - 1; - var x = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); var mock = { diff --git a/test/jasmine/performance_tests/image_test.js b/test/jasmine/performance_tests/image_test.js index 456b65e4bfd..f4fd2e09732 100644 --- a/test/jasmine/performance_tests/image_test.js +++ b/test/jasmine/performance_tests/image_test.js @@ -5,8 +5,13 @@ var Plotly = require('../../../lib/core'); var PlotlyImage = require('../../../lib/image'); var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +Plotly.register(PlotlyImage); + var gd = createGraphDiv(); +const samples = Array.from({ length: 9 }, (_, i) => i); +const nTimes = samples.length - 1; + var tests = [{ nx: 50, ny: 20 }, { @@ -27,8 +32,6 @@ tests.forEach(function(spec, index) { describe('Performance test image | size:' + spec.nx + 'X' + spec.ny, function() { 'use strict'; - Plotly.register(PlotlyImage); - const samples = Array.from({ length: 9 }, (_, i) => i); const nTimes = samples.length - 1; diff --git a/test/jasmine/performance_tests/scatter_test.js b/test/jasmine/performance_tests/scatter_test.js index 126ce3378dd..4b5b69436e5 100644 --- a/test/jasmine/performance_tests/scatter_test.js +++ b/test/jasmine/performance_tests/scatter_test.js @@ -6,6 +6,9 @@ var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; var gd = createGraphDiv(); +const samples = Array.from({ length: 9 }, (_, i) => i); +const nTimes = samples.length - 1; + var tests = [{ n: 1000 }, { @@ -26,9 +29,6 @@ tests.forEach(function(spec, index) { describe('Performance test scatter | size:' + spec.n, function() { 'use strict'; - const samples = Array.from({ length: 9 }, (_, i) => i); - const nTimes = samples.length - 1; - var y = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); var mock = { diff --git a/test/jasmine/performance_tests/scattergl_test.js b/test/jasmine/performance_tests/scattergl_test.js index fd899919a9b..41aa84a5abc 100644 --- a/test/jasmine/performance_tests/scattergl_test.js +++ b/test/jasmine/performance_tests/scattergl_test.js @@ -4,8 +4,13 @@ var Plotly = require('../../../lib/core'); var PlotlyScattergl = require('../../../lib/scattergl'); var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +Plotly.register(PlotlyScattergl); + var gd = createGraphDiv(); +const samples = Array.from({ length: 9 }, (_, i) => i); +const nTimes = samples.length - 1; + var tests = [{ n: 1000 }, { @@ -34,11 +39,6 @@ tests.forEach(function(spec, index) { describe('Performance test scattergl | size:' + spec.n, function() { 'use strict'; - Plotly.register(PlotlyScattergl); - - const samples = Array.from({ length: 9 }, (_, i) => i); - const nTimes = samples.length - 1; - var y = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); var mock = { diff --git a/test/jasmine/performance_tests/violin_test.js b/test/jasmine/performance_tests/violin_test.js index bd8e7c11602..3aa96a80ffc 100644 --- a/test/jasmine/performance_tests/violin_test.js +++ b/test/jasmine/performance_tests/violin_test.js @@ -5,8 +5,13 @@ var Plotly = require('../../../lib/core'); var PlotlyViolin = require('../../../lib/violin'); var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +Plotly.register(PlotlyViolin); + var gd = createGraphDiv(); +const samples = Array.from({ length: 9 }, (_, i) => i); +const nTimes = samples.length - 1; + var tests = [{ n: 1000 }, { @@ -27,11 +32,6 @@ tests.forEach(function(spec, index) { describe('Performance test violin | size:' + spec.n, function() { 'use strict'; - Plotly.register(PlotlyViolin); - - const samples = Array.from({ length: 9 }, (_, i) => i); - const nTimes = samples.length - 1; - var y = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); var mock = { From 33620b72dcd720c9930181f0bef60dcc2345aa29 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 12:24:52 -0400 Subject: [PATCH 16/46] revisit tests --- .../performance_tests/assets/constants.js | 5 + .../performance_tests/assets/post_process.js | 8 +- test/jasmine/performance_tests/bar_test.js | 3 +- test/jasmine/performance_tests/box_test.js | 3 +- .../jasmine/performance_tests/contour_test.js | 3 +- .../jasmine/performance_tests/heatmap_test.js | 3 +- .../performance_tests/histogram_test.js | 3 +- test/jasmine/performance_tests/image_test.js | 5 +- .../jasmine/performance_tests/scatter_test.js | 124 ++++++++++++++---- .../performance_tests/scattergl_test.js | 3 +- test/jasmine/performance_tests/violin_test.js | 3 +- 11 files changed, 129 insertions(+), 34 deletions(-) create mode 100644 test/jasmine/performance_tests/assets/constants.js diff --git a/test/jasmine/performance_tests/assets/constants.js b/test/jasmine/performance_tests/assets/constants.js new file mode 100644 index 00000000000..53fb3438b71 --- /dev/null +++ b/test/jasmine/performance_tests/assets/constants.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = { + nSamples: 1 +}; diff --git a/test/jasmine/performance_tests/assets/post_process.js b/test/jasmine/performance_tests/assets/post_process.js index 898df5c8e94..fc98c49d9bb 100644 --- a/test/jasmine/performance_tests/assets/post_process.js +++ b/test/jasmine/performance_tests/assets/post_process.js @@ -1,10 +1,14 @@ exports.writeRawDataAsCSV = function(traceName, allTests) { - var str = 'chart type,data points,run id,rendering time(ms)\n'; + var str = 'number of traces,chart type,data points,run id,rendering time(ms)\n'; for(var k = 0; k < allTests.length; k++) { var test = allTests[k]; for(var i = 0; i < test.raw.length; i++) { - str += traceName + ',' + test.n + ',' + i + ',' + test.raw[i] + '\n'; + str += + (test.nTraces || 1) + ',' + + (traceName + (test.mode ? '_' + test.mode : '')) + ',' + + test.n + ',' + i + ',' + + test.raw[i] + '\n'; } } diff --git a/test/jasmine/performance_tests/bar_test.js b/test/jasmine/performance_tests/bar_test.js index d455357f6c4..a86c30d66d6 100644 --- a/test/jasmine/performance_tests/bar_test.js +++ b/test/jasmine/performance_tests/bar_test.js @@ -4,12 +4,13 @@ var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyBar = require('../../../lib/bar'); var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +var nSamples = require('./assets/constants').nSamples; Plotly.register(PlotlyBar); var gd = createGraphDiv(); -const samples = Array.from({ length: 9 }, (_, i) => i); +const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; var tests = [{ diff --git a/test/jasmine/performance_tests/box_test.js b/test/jasmine/performance_tests/box_test.js index 6caf60b5afe..3a0444cec36 100644 --- a/test/jasmine/performance_tests/box_test.js +++ b/test/jasmine/performance_tests/box_test.js @@ -4,12 +4,13 @@ var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyBox = require('../../../lib/box'); var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +var nSamples = require('./assets/constants').nSamples; Plotly.register(PlotlyBox); var gd = createGraphDiv(); -const samples = Array.from({ length: 9 }, (_, i) => i); +const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; var tests = [{ diff --git a/test/jasmine/performance_tests/contour_test.js b/test/jasmine/performance_tests/contour_test.js index 3a7cff40f8f..624f5743454 100644 --- a/test/jasmine/performance_tests/contour_test.js +++ b/test/jasmine/performance_tests/contour_test.js @@ -4,12 +4,13 @@ var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyContour = require('../../../lib/contour'); var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +var nSamples = require('./assets/constants').nSamples; Plotly.register(PlotlyContour); var gd = createGraphDiv(); -const samples = Array.from({ length: 9 }, (_, i) => i); +const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; var tests = [{ diff --git a/test/jasmine/performance_tests/heatmap_test.js b/test/jasmine/performance_tests/heatmap_test.js index a28a7d19455..ef95a05627d 100644 --- a/test/jasmine/performance_tests/heatmap_test.js +++ b/test/jasmine/performance_tests/heatmap_test.js @@ -4,12 +4,13 @@ var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyHeatmap = require('../../../lib/heatmap'); var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +var nSamples = require('./assets/constants').nSamples; Plotly.register(PlotlyHeatmap); var gd = createGraphDiv(); -const samples = Array.from({ length: 9 }, (_, i) => i); +const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; var tests = [{ diff --git a/test/jasmine/performance_tests/histogram_test.js b/test/jasmine/performance_tests/histogram_test.js index 0685187e813..8d38d23852d 100644 --- a/test/jasmine/performance_tests/histogram_test.js +++ b/test/jasmine/performance_tests/histogram_test.js @@ -4,12 +4,13 @@ var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyHistogram = require('../../../lib/histogram'); var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +var nSamples = require('./assets/constants').nSamples; Plotly.register(PlotlyHistogram); var gd = createGraphDiv(); -const samples = Array.from({ length: 9 }, (_, i) => i); +const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; var tests = [{ diff --git a/test/jasmine/performance_tests/image_test.js b/test/jasmine/performance_tests/image_test.js index f4fd2e09732..12171dccbd7 100644 --- a/test/jasmine/performance_tests/image_test.js +++ b/test/jasmine/performance_tests/image_test.js @@ -4,12 +4,13 @@ var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyImage = require('../../../lib/image'); var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +var nSamples = require('./assets/constants').nSamples; Plotly.register(PlotlyImage); var gd = createGraphDiv(); -const samples = Array.from({ length: 9 }, (_, i) => i); +const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; var tests = [{ @@ -32,7 +33,7 @@ tests.forEach(function(spec, index) { describe('Performance test image | size:' + spec.nx + 'X' + spec.ny, function() { 'use strict'; - const samples = Array.from({ length: 9 }, (_, i) => i); + const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; var A = spec.nx; diff --git a/test/jasmine/performance_tests/scatter_test.js b/test/jasmine/performance_tests/scatter_test.js index 4b5b69436e5..24deb2d3ab1 100644 --- a/test/jasmine/performance_tests/scatter_test.js +++ b/test/jasmine/performance_tests/scatter_test.js @@ -3,49 +3,127 @@ var delay = require('../assets/delay'); var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +var nSamples = require('./assets/constants').nSamples; var gd = createGraphDiv(); -const samples = Array.from({ length: 9 }, (_, i) => i); +const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; var tests = [{ - n: 1000 + n: 1000, mode: 'markers', nTraces: 1 }, { - n: 2000 + n: 2000, mode: 'markers', nTraces: 1 }, { - n: 4000 + n: 4000, mode: 'markers', nTraces: 1 }, { - n: 8000 + n: 8000, mode: 'markers', nTraces: 1 }, { - n: 16000 + n: 16000, mode: 'markers', nTraces: 1 }, { - n: 32000 + n: 32000, mode: 'markers', nTraces: 1 }, { - n: 64000 + n: 64000, mode: 'markers', nTraces: 1 +}, { + n: 1000, mode: 'lines', nTraces: 1 +}, { + n: 2000, mode: 'lines', nTraces: 1 +}, { + n: 4000, mode: 'lines', nTraces: 1 +}, { + n: 8000, mode: 'lines', nTraces: 1 +}, { + n: 16000, mode: 'lines', nTraces: 1 +}, { + n: 32000, mode: 'lines', nTraces: 1 +}, { + n: 64000, mode: 'lines', nTraces: 1 +}, { + n: 1000, mode: 'markers', nTraces: 10 +}, { + n: 2000, mode: 'markers', nTraces: 10 +}, { + n: 4000, mode: 'markers', nTraces: 10 +}, { + n: 8000, mode: 'markers', nTraces: 10 +}, { + n: 16000, mode: 'markers', nTraces: 10 +}, { + n: 32000, mode: 'markers', nTraces: 10 +}, { + n: 64000, mode: 'markers', nTraces: 10 +}, { + n: 1000, mode: 'lines', nTraces: 10 +}, { + n: 2000, mode: 'lines', nTraces: 10 +}, { + n: 4000, mode: 'lines', nTraces: 10 +}, { + n: 8000, mode: 'lines', nTraces: 10 +}, { + n: 16000, mode: 'lines', nTraces: 10 +}, { + n: 32000, mode: 'lines', nTraces: 10 +}, { + n: 64000, mode: 'lines', nTraces: 10 +}, { + n: 1000, mode: 'markers', nTraces: 100 +}, { + n: 2000, mode: 'markers', nTraces: 100 +}, { + n: 4000, mode: 'markers', nTraces: 100 +}, { + n: 8000, mode: 'markers', nTraces: 100 +}, { + n: 16000, mode: 'markers', nTraces: 100 +}, { + n: 32000, mode: 'markers', nTraces: 100 +}, { + n: 64000, mode: 'markers', nTraces: 100 +}, { + n: 1000, mode: 'lines', nTraces: 100 +}, { + n: 2000, mode: 'lines', nTraces: 100 +}, { + n: 4000, mode: 'lines', nTraces: 100 +}, { + n: 8000, mode: 'lines', nTraces: 100 +}, { + n: 16000, mode: 'lines', nTraces: 100 +}, { + n: 32000, mode: 'lines', nTraces: 100 +}, { + n: 64000, mode: 'lines', nTraces: 100 }]; tests.forEach(function(spec, index) { - describe('Performance test scatter | size:' + spec.n, function() { + describe('Performance test ' + spec.nTraces + 'scatter | size:' + spec.n + ' | mode: ' + spec.mode, function() { 'use strict'; - var y = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + var startTime, endTime; - var mock = { - data: [{ - type: 'scatter', - mode: 'markers', - y: y - }], - layout: { - width: 900, - height: 400 + beforeEach(function(done) { + var y = Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + var data = []; + var nPerTrace = Math.floor(spec.n / spec.nTraces); + for(var k = 0; k < spec.nTraces; k++) { + data.push({ + type: 'scatter', + mode: spec.mode, + y: y.slice(k * nPerTrace, (k + 1) * nPerTrace), + x: Array.from({ length: nPerTrace }, (_, i) => i + k * nPerTrace) + }); } - }; - var startTime, endTime; + var mock = { + data: data, + layout: { + showlegend: false, + width: 900, + height: 400 + } + }; - beforeEach(function(done) { startTime = performance.now(); // Wait for actual rendering to complete @@ -73,7 +151,7 @@ tests.forEach(function(spec, index) { tests[index].raw[t] = delta; var nodes = d3SelectAll('g.trace.scatter'); - expect(nodes.size()).toEqual(1); + expect(nodes.size()).toEqual(spec.nTraces); if(t === nTimes && index === tests.length - 1) { writeRawDataAsCSV('scatter', tests); diff --git a/test/jasmine/performance_tests/scattergl_test.js b/test/jasmine/performance_tests/scattergl_test.js index 41aa84a5abc..1cbc97e9cfe 100644 --- a/test/jasmine/performance_tests/scattergl_test.js +++ b/test/jasmine/performance_tests/scattergl_test.js @@ -3,12 +3,13 @@ var delay = require('../assets/delay'); var Plotly = require('../../../lib/core'); var PlotlyScattergl = require('../../../lib/scattergl'); var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +var nSamples = require('./assets/constants').nSamples; Plotly.register(PlotlyScattergl); var gd = createGraphDiv(); -const samples = Array.from({ length: 9 }, (_, i) => i); +const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; var tests = [{ diff --git a/test/jasmine/performance_tests/violin_test.js b/test/jasmine/performance_tests/violin_test.js index 3aa96a80ffc..5b56f2b8bbd 100644 --- a/test/jasmine/performance_tests/violin_test.js +++ b/test/jasmine/performance_tests/violin_test.js @@ -4,12 +4,13 @@ var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyViolin = require('../../../lib/violin'); var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +var nSamples = require('./assets/constants').nSamples; Plotly.register(PlotlyViolin); var gd = createGraphDiv(); -const samples = Array.from({ length: 9 }, (_, i) => i); +const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; var tests = [{ From b6dac795bbff219dc4677586a023311472822085 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 12:42:37 -0400 Subject: [PATCH 17/46] extend scattergl --- .../performance_tests/scattergl_test.js | 119 ++++++++++++++---- 1 file changed, 94 insertions(+), 25 deletions(-) diff --git a/test/jasmine/performance_tests/scattergl_test.js b/test/jasmine/performance_tests/scattergl_test.js index 1cbc97e9cfe..55c0aa6bf5c 100644 --- a/test/jasmine/performance_tests/scattergl_test.js +++ b/test/jasmine/performance_tests/scattergl_test.js @@ -13,50 +13,119 @@ const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; var tests = [{ - n: 1000 + n: 1000, mode: 'markers', nTraces: 1 }, { - n: 2000 + n: 2000, mode: 'markers', nTraces: 1 }, { - n: 4000 + n: 4000, mode: 'markers', nTraces: 1 }, { - n: 8000 + n: 8000, mode: 'markers', nTraces: 1 }, { - n: 16000 + n: 16000, mode: 'markers', nTraces: 1 }, { - n: 32000 + n: 32000, mode: 'markers', nTraces: 1 }, { - n: 64000 + n: 64000, mode: 'markers', nTraces: 1 }, { - n: 128000 + n: 1000, mode: 'lines', nTraces: 1 }, { - n: 256000 + n: 2000, mode: 'lines', nTraces: 1 }, { - n: 512000 + n: 4000, mode: 'lines', nTraces: 1 }, { - n: 1024000 + n: 8000, mode: 'lines', nTraces: 1 +}, { + n: 16000, mode: 'lines', nTraces: 1 +}, { + n: 32000, mode: 'lines', nTraces: 1 +}, { + n: 64000, mode: 'lines', nTraces: 1 +}, { + n: 1000, mode: 'markers', nTraces: 10 +}, { + n: 2000, mode: 'markers', nTraces: 10 +}, { + n: 4000, mode: 'markers', nTraces: 10 +}, { + n: 8000, mode: 'markers', nTraces: 10 +}, { + n: 16000, mode: 'markers', nTraces: 10 +}, { + n: 32000, mode: 'markers', nTraces: 10 +}, { + n: 64000, mode: 'markers', nTraces: 10 +}, { + n: 1000, mode: 'lines', nTraces: 10 +}, { + n: 2000, mode: 'lines', nTraces: 10 +}, { + n: 4000, mode: 'lines', nTraces: 10 +}, { + n: 8000, mode: 'lines', nTraces: 10 +}, { + n: 16000, mode: 'lines', nTraces: 10 +}, { + n: 32000, mode: 'lines', nTraces: 10 +}, { + n: 64000, mode: 'lines', nTraces: 10 +}, { + n: 1000, mode: 'markers', nTraces: 100 +}, { + n: 2000, mode: 'markers', nTraces: 100 +}, { + n: 4000, mode: 'markers', nTraces: 100 +}, { + n: 8000, mode: 'markers', nTraces: 100 +}, { + n: 16000, mode: 'markers', nTraces: 100 +}, { + n: 32000, mode: 'markers', nTraces: 100 +}, { + n: 64000, mode: 'markers', nTraces: 100 +}, { + n: 1000, mode: 'lines', nTraces: 100 +}, { + n: 2000, mode: 'lines', nTraces: 100 +}, { + n: 4000, mode: 'lines', nTraces: 100 +}, { + n: 8000, mode: 'lines', nTraces: 100 +}, { + n: 16000, mode: 'lines', nTraces: 100 +}, { + n: 32000, mode: 'lines', nTraces: 100 +}, { + n: 64000, mode: 'lines', nTraces: 100 }]; tests.forEach(function(spec, index) { - describe('Performance test scattergl | size:' + spec.n, function() { + describe('Performance test ' + spec.nTraces + 'scattergl | size:' + spec.n + ' | mode: ' + spec.mode, function() { 'use strict'; - var y = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + var startTime, endTime; - var mock = { - data: [{ - type: 'scattergl', - mode: 'markers', - y: y - }], - layout: { - width: 900, - height: 400 + beforeEach(function(done) { + var y = Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + var data = []; + var nPerTrace = Math.floor(spec.n / spec.nTraces); + for(var k = 0; k < spec.nTraces; k++) { + data.push({ + type: 'scattergl', + mode: spec.mode, + y: y.slice(k * nPerTrace, (k + 1) * nPerTrace), + x: Array.from({ length: nPerTrace }, (_, i) => i + k * nPerTrace) + }); } - }; - var startTime, endTime; + var mock = { + data: data, + layout: { + showlegend: false, + width: 900, + height: 400 + } + }; - beforeEach(function(done) { startTime = performance.now(); // Wait for actual rendering to complete From 543478e7fbaedc56a9da21c4d435859d20b4ce62 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 13:01:22 -0400 Subject: [PATCH 18/46] extend bar --- test/jasmine/performance_tests/bar_test.js | 120 +++++++++++++++++---- 1 file changed, 99 insertions(+), 21 deletions(-) diff --git a/test/jasmine/performance_tests/bar_test.js b/test/jasmine/performance_tests/bar_test.js index a86c30d66d6..a45716a1a09 100644 --- a/test/jasmine/performance_tests/bar_test.js +++ b/test/jasmine/performance_tests/bar_test.js @@ -14,41 +14,119 @@ const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; var tests = [{ - n: 1000 + n: 1000, mode: 'group', nTraces: 1 }, { - n: 2000 + n: 2000, mode: 'group', nTraces: 1 }, { - n: 4000 + n: 4000, mode: 'group', nTraces: 1 }, { - n: 8000 + n: 8000, mode: 'group', nTraces: 1 }, { - n: 16000 + n: 16000, mode: 'group', nTraces: 1 }, { - n: 32000 + n: 32000, mode: 'group', nTraces: 1 }, { - n: 64000 + n: 64000, mode: 'group', nTraces: 1 +}, { + n: 1000, mode: 'stack', nTraces: 1 +}, { + n: 2000, mode: 'stack', nTraces: 1 +}, { + n: 4000, mode: 'stack', nTraces: 1 +}, { + n: 8000, mode: 'stack', nTraces: 1 +}, { + n: 16000, mode: 'stack', nTraces: 1 +}, { + n: 32000, mode: 'stack', nTraces: 1 +}, { + n: 64000, mode: 'stack', nTraces: 1 +}, { + n: 1000, mode: 'group', nTraces: 10 +}, { + n: 2000, mode: 'group', nTraces: 10 +}, { + n: 4000, mode: 'group', nTraces: 10 +}, { + n: 8000, mode: 'group', nTraces: 10 +}, { + n: 16000, mode: 'group', nTraces: 10 +}, { + n: 32000, mode: 'group', nTraces: 10 +}, { + n: 64000, mode: 'group', nTraces: 10 +}, { + n: 1000, mode: 'stack', nTraces: 10 +}, { + n: 2000, mode: 'stack', nTraces: 10 +}, { + n: 4000, mode: 'stack', nTraces: 10 +}, { + n: 8000, mode: 'stack', nTraces: 10 +}, { + n: 16000, mode: 'stack', nTraces: 10 +}, { + n: 32000, mode: 'stack', nTraces: 10 +}, { + n: 64000, mode: 'stack', nTraces: 10 +}, { + n: 1000, mode: 'group', nTraces: 100 +}, { + n: 2000, mode: 'group', nTraces: 100 +}, { + n: 4000, mode: 'group', nTraces: 100 +}, { + n: 8000, mode: 'group', nTraces: 100 +}, { + n: 16000, mode: 'group', nTraces: 100 +}, { + n: 32000, mode: 'group', nTraces: 100 +}, { + n: 64000, mode: 'group', nTraces: 100 +}, { + n: 1000, mode: 'stack', nTraces: 100 +}, { + n: 2000, mode: 'stack', nTraces: 100 +}, { + n: 4000, mode: 'stack', nTraces: 100 +}, { + n: 8000, mode: 'stack', nTraces: 100 +}, { + n: 16000, mode: 'stack', nTraces: 100 +}, { + n: 32000, mode: 'stack', nTraces: 100 +}, { + n: 64000, mode: 'stack', nTraces: 100 }]; tests.forEach(function(spec, index) { - describe('Performance test bar | size:' + spec.n, function() { + describe('Performance test ' + spec.nTraces + 'bar | size:' + spec.n + ' | mode: ' + spec.mode, function() { 'use strict'; - var y = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + var startTime, endTime; - var mock = { - data: [{ - type: 'bar', - y: y - }], - layout: { - width: 900, - height: 400 + beforeEach(function(done) { + var y = Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + var data = []; + var nPerTrace = Math.floor(spec.n / spec.nTraces); + for(var k = 0; k < spec.nTraces; k++) { + data.push({ + type: 'bar', + y: y.slice(k * nPerTrace, (k + 1) * nPerTrace), + x: Array.from({ length: nPerTrace }, (_, i) => i) + }); } - }; - var startTime, endTime; + var mock = { + data: data, + layout: { + barmode: spec.mode, + showlegend: false, + width: 900, + height: 400 + } + }; - beforeEach(function(done) { startTime = performance.now(); // Wait for actual rendering to complete @@ -76,7 +154,7 @@ tests.forEach(function(spec, index) { tests[index].raw[t] = delta; var nodes = d3SelectAll('g.trace.bars'); - expect(nodes.size()).toEqual(1); + expect(nodes.size()).toEqual(spec.nTraces); if(t === nTimes && index === tests.length - 1) { writeRawDataAsCSV('bar', tests); From ff93b2edd7d174be5998ef59761b2f52a1e7966d Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 13:09:55 -0400 Subject: [PATCH 19/46] extend box --- test/jasmine/performance_tests/box_test.js | 123 +++++++++++++++++---- 1 file changed, 100 insertions(+), 23 deletions(-) diff --git a/test/jasmine/performance_tests/box_test.js b/test/jasmine/performance_tests/box_test.js index 3a0444cec36..35d64d43a5f 100644 --- a/test/jasmine/performance_tests/box_test.js +++ b/test/jasmine/performance_tests/box_test.js @@ -14,42 +14,119 @@ const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; var tests = [{ - n: 1000 + n: 1000, mode: 'no points', nTraces: 1 }, { - n: 2000 + n: 2000, mode: 'no points', nTraces: 1 }, { - n: 4000 + n: 4000, mode: 'no points', nTraces: 1 }, { - n: 8000 + n: 8000, mode: 'no points', nTraces: 1 }, { - n: 16000 + n: 16000, mode: 'no points', nTraces: 1 }, { - n: 32000 + n: 32000, mode: 'no points', nTraces: 1 }, { - n: 64000 + n: 64000, mode: 'no points', nTraces: 1 +}, { + n: 1000, mode: 'all points', nTraces: 1 +}, { + n: 2000, mode: 'all points', nTraces: 1 +}, { + n: 4000, mode: 'all points', nTraces: 1 +}, { + n: 8000, mode: 'all points', nTraces: 1 +}, { + n: 16000, mode: 'all points', nTraces: 1 +}, { + n: 32000, mode: 'all points', nTraces: 1 +}, { + n: 64000, mode: 'all points', nTraces: 1 +}, { + n: 1000, mode: 'no points', nTraces: 10 +}, { + n: 2000, mode: 'no points', nTraces: 10 +}, { + n: 4000, mode: 'no points', nTraces: 10 +}, { + n: 8000, mode: 'no points', nTraces: 10 +}, { + n: 16000, mode: 'no points', nTraces: 10 +}, { + n: 32000, mode: 'no points', nTraces: 10 +}, { + n: 64000, mode: 'no points', nTraces: 10 +}, { + n: 1000, mode: 'all points', nTraces: 10 +}, { + n: 2000, mode: 'all points', nTraces: 10 +}, { + n: 4000, mode: 'all points', nTraces: 10 +}, { + n: 8000, mode: 'all points', nTraces: 10 +}, { + n: 16000, mode: 'all points', nTraces: 10 +}, { + n: 32000, mode: 'all points', nTraces: 10 +}, { + n: 64000, mode: 'all points', nTraces: 10 +}, { + n: 1000, mode: 'no points', nTraces: 100 +}, { + n: 2000, mode: 'no points', nTraces: 100 +}, { + n: 4000, mode: 'no points', nTraces: 100 +}, { + n: 8000, mode: 'no points', nTraces: 100 +}, { + n: 16000, mode: 'no points', nTraces: 100 +}, { + n: 32000, mode: 'no points', nTraces: 100 +}, { + n: 64000, mode: 'no points', nTraces: 100 +}, { + n: 1000, mode: 'all points', nTraces: 100 +}, { + n: 2000, mode: 'all points', nTraces: 100 +}, { + n: 4000, mode: 'all points', nTraces: 100 +}, { + n: 8000, mode: 'all points', nTraces: 100 +}, { + n: 16000, mode: 'all points', nTraces: 100 +}, { + n: 32000, mode: 'all points', nTraces: 100 +}, { + n: 64000, mode: 'all points', nTraces: 100 }]; tests.forEach(function(spec, index) { - describe('Performance test box | size:' + spec.n, function() { + describe('Performance test ' + spec.nTraces + 'box | size:' + spec.n + ' | mode: ' + spec.mode, function() { 'use strict'; - var y = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); - - var mock = { - data: [{ - type: 'box', - boxpoints: 'all', - y: y - }], - layout: { - width: 900, - height: 400 - } - }; - var startTime, endTime; beforeEach(function(done) { + var y = Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + var data = []; + var nPerTrace = Math.floor(spec.n / spec.nTraces); + for(var k = 0; k < spec.nTraces; k++) { + data.push({ + type: 'box', + boxpoints: spec.mode === 'all points' ? 'all' : false, + y: y.slice(k * nPerTrace, (k + 1) * nPerTrace), + x: Array.from({ length: nPerTrace }, (_, i) => k) + }); + } + + var mock = { + data: data, + layout: { + showlegend: false, + width: 900, + height: 400 + } + }; + startTime = performance.now(); // Wait for actual rendering to complete @@ -77,7 +154,7 @@ tests.forEach(function(spec, index) { tests[index].raw[t] = delta; var nodes = d3SelectAll('g.trace.boxes'); - expect(nodes.size()).toEqual(1); + expect(nodes.size()).toEqual(spec.nTraces); if(t === nTimes && index === tests.length - 1) { writeRawDataAsCSV('box', tests); From e3cd7b5dd8a6f4c684f24447da546b1ca5d9aba3 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 13:12:32 -0400 Subject: [PATCH 20/46] extend violin --- test/jasmine/performance_tests/violin_test.js | 123 ++++++++++++++---- 1 file changed, 100 insertions(+), 23 deletions(-) diff --git a/test/jasmine/performance_tests/violin_test.js b/test/jasmine/performance_tests/violin_test.js index 5b56f2b8bbd..9c53a1deca1 100644 --- a/test/jasmine/performance_tests/violin_test.js +++ b/test/jasmine/performance_tests/violin_test.js @@ -14,42 +14,119 @@ const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; var tests = [{ - n: 1000 + n: 1000, mode: 'no points', nTraces: 1 }, { - n: 2000 + n: 2000, mode: 'no points', nTraces: 1 }, { - n: 4000 + n: 4000, mode: 'no points', nTraces: 1 }, { - n: 8000 + n: 8000, mode: 'no points', nTraces: 1 }, { - n: 16000 + n: 16000, mode: 'no points', nTraces: 1 }, { - n: 32000 + n: 32000, mode: 'no points', nTraces: 1 }, { - n: 64000 + n: 64000, mode: 'no points', nTraces: 1 +}, { + n: 1000, mode: 'all points', nTraces: 1 +}, { + n: 2000, mode: 'all points', nTraces: 1 +}, { + n: 4000, mode: 'all points', nTraces: 1 +}, { + n: 8000, mode: 'all points', nTraces: 1 +}, { + n: 16000, mode: 'all points', nTraces: 1 +}, { + n: 32000, mode: 'all points', nTraces: 1 +}, { + n: 64000, mode: 'all points', nTraces: 1 +}, { + n: 1000, mode: 'no points', nTraces: 10 +}, { + n: 2000, mode: 'no points', nTraces: 10 +}, { + n: 4000, mode: 'no points', nTraces: 10 +}, { + n: 8000, mode: 'no points', nTraces: 10 +}, { + n: 16000, mode: 'no points', nTraces: 10 +}, { + n: 32000, mode: 'no points', nTraces: 10 +}, { + n: 64000, mode: 'no points', nTraces: 10 +}, { + n: 1000, mode: 'all points', nTraces: 10 +}, { + n: 2000, mode: 'all points', nTraces: 10 +}, { + n: 4000, mode: 'all points', nTraces: 10 +}, { + n: 8000, mode: 'all points', nTraces: 10 +}, { + n: 16000, mode: 'all points', nTraces: 10 +}, { + n: 32000, mode: 'all points', nTraces: 10 +}, { + n: 64000, mode: 'all points', nTraces: 10 +}, { + n: 1000, mode: 'no points', nTraces: 100 +}, { + n: 2000, mode: 'no points', nTraces: 100 +}, { + n: 4000, mode: 'no points', nTraces: 100 +}, { + n: 8000, mode: 'no points', nTraces: 100 +}, { + n: 16000, mode: 'no points', nTraces: 100 +}, { + n: 32000, mode: 'no points', nTraces: 100 +}, { + n: 64000, mode: 'no points', nTraces: 100 +}, { + n: 1000, mode: 'all points', nTraces: 100 +}, { + n: 2000, mode: 'all points', nTraces: 100 +}, { + n: 4000, mode: 'all points', nTraces: 100 +}, { + n: 8000, mode: 'all points', nTraces: 100 +}, { + n: 16000, mode: 'all points', nTraces: 100 +}, { + n: 32000, mode: 'all points', nTraces: 100 +}, { + n: 64000, mode: 'all points', nTraces: 100 }]; tests.forEach(function(spec, index) { - describe('Performance test violin | size:' + spec.n, function() { + describe('Performance test ' + spec.nTraces + 'violin | size:' + spec.n + ' | mode: ' + spec.mode, function() { 'use strict'; - var y = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); - - var mock = { - data: [{ - type: 'violin', - points: 'all', - y: y - }], - layout: { - width: 900, - height: 400 - } - }; - var startTime, endTime; beforeEach(function(done) { + var y = Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + var data = []; + var nPerTrace = Math.floor(spec.n / spec.nTraces); + for(var k = 0; k < spec.nTraces; k++) { + data.push({ + type: 'violin', + points: spec.mode === 'all points' ? 'all' : false, + y: y.slice(k * nPerTrace, (k + 1) * nPerTrace), + x: Array.from({ length: nPerTrace }, (_, i) => k) + }); + } + + var mock = { + data: data, + layout: { + showlegend: false, + width: 900, + height: 400 + } + }; + startTime = performance.now(); // Wait for actual rendering to complete @@ -77,7 +154,7 @@ tests.forEach(function(spec, index) { tests[index].raw[t] = delta; var nodes = d3SelectAll('g.trace.violins'); - expect(nodes.size()).toEqual(1); + expect(nodes.size()).toEqual(spec.nTraces); if(t === nTimes && index === tests.length - 1) { writeRawDataAsCSV('violin', tests); From 0b0642ac82368e9c1d044df4376d87a98fc2281e Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 13:15:55 -0400 Subject: [PATCH 21/46] extend histogram --- .../performance_tests/histogram_test.js | 120 +++++++++++++++--- 1 file changed, 99 insertions(+), 21 deletions(-) diff --git a/test/jasmine/performance_tests/histogram_test.js b/test/jasmine/performance_tests/histogram_test.js index 8d38d23852d..81b5986dca2 100644 --- a/test/jasmine/performance_tests/histogram_test.js +++ b/test/jasmine/performance_tests/histogram_test.js @@ -14,41 +14,119 @@ const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; var tests = [{ - n: 1000 + n: 1000, mode: 'group', nTraces: 1 }, { - n: 2000 + n: 2000, mode: 'group', nTraces: 1 }, { - n: 4000 + n: 4000, mode: 'group', nTraces: 1 }, { - n: 8000 + n: 8000, mode: 'group', nTraces: 1 }, { - n: 16000 + n: 16000, mode: 'group', nTraces: 1 }, { - n: 32000 + n: 32000, mode: 'group', nTraces: 1 }, { - n: 64000 + n: 64000, mode: 'group', nTraces: 1 +}, { + n: 1000, mode: 'stack', nTraces: 1 +}, { + n: 2000, mode: 'stack', nTraces: 1 +}, { + n: 4000, mode: 'stack', nTraces: 1 +}, { + n: 8000, mode: 'stack', nTraces: 1 +}, { + n: 16000, mode: 'stack', nTraces: 1 +}, { + n: 32000, mode: 'stack', nTraces: 1 +}, { + n: 64000, mode: 'stack', nTraces: 1 +}, { + n: 1000, mode: 'group', nTraces: 10 +}, { + n: 2000, mode: 'group', nTraces: 10 +}, { + n: 4000, mode: 'group', nTraces: 10 +}, { + n: 8000, mode: 'group', nTraces: 10 +}, { + n: 16000, mode: 'group', nTraces: 10 +}, { + n: 32000, mode: 'group', nTraces: 10 +}, { + n: 64000, mode: 'group', nTraces: 10 +}, { + n: 1000, mode: 'stack', nTraces: 10 +}, { + n: 2000, mode: 'stack', nTraces: 10 +}, { + n: 4000, mode: 'stack', nTraces: 10 +}, { + n: 8000, mode: 'stack', nTraces: 10 +}, { + n: 16000, mode: 'stack', nTraces: 10 +}, { + n: 32000, mode: 'stack', nTraces: 10 +}, { + n: 64000, mode: 'stack', nTraces: 10 +}, { + n: 1000, mode: 'group', nTraces: 100 +}, { + n: 2000, mode: 'group', nTraces: 100 +}, { + n: 4000, mode: 'group', nTraces: 100 +}, { + n: 8000, mode: 'group', nTraces: 100 +}, { + n: 16000, mode: 'group', nTraces: 100 +}, { + n: 32000, mode: 'group', nTraces: 100 +}, { + n: 64000, mode: 'group', nTraces: 100 +}, { + n: 1000, mode: 'stack', nTraces: 100 +}, { + n: 2000, mode: 'stack', nTraces: 100 +}, { + n: 4000, mode: 'stack', nTraces: 100 +}, { + n: 8000, mode: 'stack', nTraces: 100 +}, { + n: 16000, mode: 'stack', nTraces: 100 +}, { + n: 32000, mode: 'stack', nTraces: 100 +}, { + n: 64000, mode: 'stack', nTraces: 100 }]; tests.forEach(function(spec, index) { - describe('Performance test histogram | size:' + spec.n, function() { + describe('Performance test ' + spec.nTraces + 'histogram | size:' + spec.n + ' | mode: ' + spec.mode, function() { 'use strict'; - var x = Float64Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + var startTime, endTime; - var mock = { - data: [{ - type: 'histogram', - x: x - }], - layout: { - width: 900, - height: 400 + beforeEach(function(done) { + var z = Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + var data = []; + var nPerTrace = Math.floor(spec.n / spec.nTraces); + for(var k = 0; k < spec.nTraces; k++) { + data.push({ + type: 'histogram', + x: z.slice(k * nPerTrace, (k + 1) * nPerTrace), + y: Array.from({ length: nPerTrace }, (_, i) => i) + }); } - }; - var startTime, endTime; + var mock = { + data: data, + layout: { + barmode: spec.mode, + showlegend: false, + width: 900, + height: 400 + } + }; - beforeEach(function(done) { startTime = performance.now(); // Wait for actual rendering to complete @@ -76,7 +154,7 @@ tests.forEach(function(spec, index) { tests[index].raw[t] = delta; var nodes = d3SelectAll('g.trace.bars'); - expect(nodes.size()).toEqual(1); + expect(nodes.size()).toEqual(spec.nTraces); if(t === nTimes && index === tests.length - 1) { writeRawDataAsCSV('histogram', tests); From 1227e2a07730c878031f7207cd001773fb96a3d1 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 14:07:20 -0400 Subject: [PATCH 22/46] revise download csv --- .../performance_tests/assets/post_process.js | 26 ++++++++++++------- test/jasmine/performance_tests/bar_test.js | 4 +-- test/jasmine/performance_tests/box_test.js | 4 +-- .../jasmine/performance_tests/contour_test.js | 4 +-- .../jasmine/performance_tests/heatmap_test.js | 4 +-- .../performance_tests/histogram_test.js | 4 +-- test/jasmine/performance_tests/image_test.js | 4 +-- .../jasmine/performance_tests/scatter_test.js | 4 +-- .../performance_tests/scattergl_test.js | 4 +-- test/jasmine/performance_tests/violin_test.js | 4 +-- 10 files changed, 34 insertions(+), 28 deletions(-) diff --git a/test/jasmine/performance_tests/assets/post_process.js b/test/jasmine/performance_tests/assets/post_process.js index fc98c49d9bb..5172d0eb1db 100644 --- a/test/jasmine/performance_tests/assets/post_process.js +++ b/test/jasmine/performance_tests/assets/post_process.js @@ -1,20 +1,26 @@ -exports.writeRawDataAsCSV = function(traceName, allTests) { - var str = 'number of traces,chart type,data points,run id,rendering time(ms)\n'; +exports.downloadCSV = function(traceName, allTests) { + var str = [ + 'number of traces', + 'chart type', + 'data points', + 'run id', + 'rendering time(ms)' + ].join(',') + '\n'; for(var k = 0; k < allTests.length; k++) { var test = allTests[k]; for(var i = 0; i < test.raw.length; i++) { - str += - (test.nTraces || 1) + ',' + - (traceName + (test.mode ? '_' + test.mode : '')) + ',' + - test.n + ',' + i + ',' + - test.raw[i] + '\n'; + str += [ + (test.nTraces || 1), + (traceName + (test.mode ? ' ' + test.mode : '')), + test.n, + i, + test.raw[i] + ].join(',') + '\n'; } } - console.log(str); - - // download a CSV file + // download file by browser var a = document.createElement('a'); var myBlob = new Blob([str], {type: 'text/plain'}) var url = window.URL.createObjectURL(myBlob); diff --git a/test/jasmine/performance_tests/bar_test.js b/test/jasmine/performance_tests/bar_test.js index a45716a1a09..9edca9ec1b9 100644 --- a/test/jasmine/performance_tests/bar_test.js +++ b/test/jasmine/performance_tests/bar_test.js @@ -3,7 +3,7 @@ var delay = require('../assets/delay'); var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyBar = require('../../../lib/bar'); -var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +var downloadCSV = require('./assets/post_process').downloadCSV; var nSamples = require('./assets/constants').nSamples; Plotly.register(PlotlyBar); @@ -157,7 +157,7 @@ tests.forEach(function(spec, index) { expect(nodes.size()).toEqual(spec.nTraces); if(t === nTimes && index === tests.length - 1) { - writeRawDataAsCSV('bar', tests); + downloadCSV('bar', tests); } }); }); diff --git a/test/jasmine/performance_tests/box_test.js b/test/jasmine/performance_tests/box_test.js index 35d64d43a5f..e5a7bae6678 100644 --- a/test/jasmine/performance_tests/box_test.js +++ b/test/jasmine/performance_tests/box_test.js @@ -3,7 +3,7 @@ var delay = require('../assets/delay'); var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyBox = require('../../../lib/box'); -var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +var downloadCSV = require('./assets/post_process').downloadCSV; var nSamples = require('./assets/constants').nSamples; Plotly.register(PlotlyBox); @@ -157,7 +157,7 @@ tests.forEach(function(spec, index) { expect(nodes.size()).toEqual(spec.nTraces); if(t === nTimes && index === tests.length - 1) { - writeRawDataAsCSV('box', tests); + downloadCSV('box', tests); } }); }); diff --git a/test/jasmine/performance_tests/contour_test.js b/test/jasmine/performance_tests/contour_test.js index 624f5743454..c38e1722b02 100644 --- a/test/jasmine/performance_tests/contour_test.js +++ b/test/jasmine/performance_tests/contour_test.js @@ -3,7 +3,7 @@ var delay = require('../assets/delay'); var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyContour = require('../../../lib/contour'); -var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +var downloadCSV = require('./assets/post_process').downloadCSV; var nSamples = require('./assets/constants').nSamples; Plotly.register(PlotlyContour); @@ -90,7 +90,7 @@ tests.forEach(function(spec, index) { expect(nodes.size()).toEqual(1); if(t === nTimes && index === tests.length - 1) { - writeRawDataAsCSV('contour', tests); + downloadCSV('contour', tests); } }); }); diff --git a/test/jasmine/performance_tests/heatmap_test.js b/test/jasmine/performance_tests/heatmap_test.js index ef95a05627d..0c0ae151e77 100644 --- a/test/jasmine/performance_tests/heatmap_test.js +++ b/test/jasmine/performance_tests/heatmap_test.js @@ -3,7 +3,7 @@ var delay = require('../assets/delay'); var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyHeatmap = require('../../../lib/heatmap'); -var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +var downloadCSV = require('./assets/post_process').downloadCSV; var nSamples = require('./assets/constants').nSamples; Plotly.register(PlotlyHeatmap); @@ -90,7 +90,7 @@ tests.forEach(function(spec, index) { expect(nodes.size()).toEqual(1); if(t === nTimes && index === tests.length - 1) { - writeRawDataAsCSV('heatmap', tests); + downloadCSV('heatmap', tests); } }); }); diff --git a/test/jasmine/performance_tests/histogram_test.js b/test/jasmine/performance_tests/histogram_test.js index 81b5986dca2..ccf3e75782f 100644 --- a/test/jasmine/performance_tests/histogram_test.js +++ b/test/jasmine/performance_tests/histogram_test.js @@ -3,7 +3,7 @@ var delay = require('../assets/delay'); var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyHistogram = require('../../../lib/histogram'); -var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +var downloadCSV = require('./assets/post_process').downloadCSV; var nSamples = require('./assets/constants').nSamples; Plotly.register(PlotlyHistogram); @@ -157,7 +157,7 @@ tests.forEach(function(spec, index) { expect(nodes.size()).toEqual(spec.nTraces); if(t === nTimes && index === tests.length - 1) { - writeRawDataAsCSV('histogram', tests); + downloadCSV('histogram', tests); } }); }); diff --git a/test/jasmine/performance_tests/image_test.js b/test/jasmine/performance_tests/image_test.js index 12171dccbd7..39ddf256477 100644 --- a/test/jasmine/performance_tests/image_test.js +++ b/test/jasmine/performance_tests/image_test.js @@ -3,7 +3,7 @@ var delay = require('../assets/delay'); var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyImage = require('../../../lib/image'); -var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +var downloadCSV = require('./assets/post_process').downloadCSV; var nSamples = require('./assets/constants').nSamples; Plotly.register(PlotlyImage); @@ -100,7 +100,7 @@ tests.forEach(function(spec, index) { expect(nodes.size()).toEqual(1); if(t === nTimes && index === tests.length - 1) { - writeRawDataAsCSV('image', tests); + downloadCSV('image', tests); } }); }); diff --git a/test/jasmine/performance_tests/scatter_test.js b/test/jasmine/performance_tests/scatter_test.js index 24deb2d3ab1..c08425a87ee 100644 --- a/test/jasmine/performance_tests/scatter_test.js +++ b/test/jasmine/performance_tests/scatter_test.js @@ -2,7 +2,7 @@ var createGraphDiv = require('../assets/create_graph_div'); var delay = require('../assets/delay'); var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); -var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +var downloadCSV = require('./assets/post_process').downloadCSV; var nSamples = require('./assets/constants').nSamples; var gd = createGraphDiv(); @@ -154,7 +154,7 @@ tests.forEach(function(spec, index) { expect(nodes.size()).toEqual(spec.nTraces); if(t === nTimes && index === tests.length - 1) { - writeRawDataAsCSV('scatter', tests); + downloadCSV('scatter', tests); } }); }); diff --git a/test/jasmine/performance_tests/scattergl_test.js b/test/jasmine/performance_tests/scattergl_test.js index 55c0aa6bf5c..303aaa4f138 100644 --- a/test/jasmine/performance_tests/scattergl_test.js +++ b/test/jasmine/performance_tests/scattergl_test.js @@ -2,7 +2,7 @@ var createGraphDiv = require('../assets/create_graph_div'); var delay = require('../assets/delay'); var Plotly = require('../../../lib/core'); var PlotlyScattergl = require('../../../lib/scattergl'); -var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +var downloadCSV = require('./assets/post_process').downloadCSV; var nSamples = require('./assets/constants').nSamples; Plotly.register(PlotlyScattergl); @@ -153,7 +153,7 @@ tests.forEach(function(spec, index) { tests[index].raw[t] = delta; if(t === nTimes && index === tests.length - 1) { - writeRawDataAsCSV('scattergl', tests); + downloadCSV('scattergl', tests); } }); }); diff --git a/test/jasmine/performance_tests/violin_test.js b/test/jasmine/performance_tests/violin_test.js index 9c53a1deca1..75a779d38d4 100644 --- a/test/jasmine/performance_tests/violin_test.js +++ b/test/jasmine/performance_tests/violin_test.js @@ -3,7 +3,7 @@ var delay = require('../assets/delay'); var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/core'); var PlotlyViolin = require('../../../lib/violin'); -var writeRawDataAsCSV = require('./assets/post_process').writeRawDataAsCSV; +var downloadCSV = require('./assets/post_process').downloadCSV; var nSamples = require('./assets/constants').nSamples; Plotly.register(PlotlyViolin); @@ -157,7 +157,7 @@ tests.forEach(function(spec, index) { expect(nodes.size()).toEqual(spec.nTraces); if(t === nTimes && index === tests.length - 1) { - writeRawDataAsCSV('violin', tests); + downloadCSV('violin', tests); } }); }); From cd5da3255f1a336576818f19df44cfeaf61b5ac3 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 14:14:15 -0400 Subject: [PATCH 23/46] add markers+lines cases --- .../jasmine/performance_tests/scatter_test.js | 42 +++++++++++++++++++ .../performance_tests/scattergl_test.js | 42 +++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/test/jasmine/performance_tests/scatter_test.js b/test/jasmine/performance_tests/scatter_test.js index c08425a87ee..001f8125b16 100644 --- a/test/jasmine/performance_tests/scatter_test.js +++ b/test/jasmine/performance_tests/scatter_test.js @@ -38,6 +38,20 @@ var tests = [{ n: 32000, mode: 'lines', nTraces: 1 }, { n: 64000, mode: 'lines', nTraces: 1 +}, { + n: 1000, mode: 'markers+lines', nTraces: 1 +}, { + n: 2000, mode: 'markers+lines', nTraces: 1 +}, { + n: 4000, mode: 'markers+lines', nTraces: 1 +}, { + n: 8000, mode: 'markers+lines', nTraces: 1 +}, { + n: 16000, mode: 'markers+lines', nTraces: 1 +}, { + n: 32000, mode: 'markers+lines', nTraces: 1 +}, { + n: 64000, mode: 'markers+lines', nTraces: 1 }, { n: 1000, mode: 'markers', nTraces: 10 }, { @@ -66,6 +80,20 @@ var tests = [{ n: 32000, mode: 'lines', nTraces: 10 }, { n: 64000, mode: 'lines', nTraces: 10 +}, { + n: 1000, mode: 'markers+lines', nTraces: 10 +}, { + n: 2000, mode: 'markers+lines', nTraces: 10 +}, { + n: 4000, mode: 'markers+lines', nTraces: 10 +}, { + n: 8000, mode: 'markers+lines', nTraces: 10 +}, { + n: 16000, mode: 'markers+lines', nTraces: 10 +}, { + n: 32000, mode: 'markers+lines', nTraces: 10 +}, { + n: 64000, mode: 'markers+lines', nTraces: 10 }, { n: 1000, mode: 'markers', nTraces: 100 }, { @@ -94,6 +122,20 @@ var tests = [{ n: 32000, mode: 'lines', nTraces: 100 }, { n: 64000, mode: 'lines', nTraces: 100 +}, { + n: 1000, mode: 'markers+lines', nTraces: 100 +}, { + n: 2000, mode: 'markers+lines', nTraces: 100 +}, { + n: 4000, mode: 'markers+lines', nTraces: 100 +}, { + n: 8000, mode: 'markers+lines', nTraces: 100 +}, { + n: 16000, mode: 'markers+lines', nTraces: 100 +}, { + n: 32000, mode: 'markers+lines', nTraces: 100 +}, { + n: 64000, mode: 'markers+lines', nTraces: 100 }]; tests.forEach(function(spec, index) { diff --git a/test/jasmine/performance_tests/scattergl_test.js b/test/jasmine/performance_tests/scattergl_test.js index 303aaa4f138..f415efd58c2 100644 --- a/test/jasmine/performance_tests/scattergl_test.js +++ b/test/jasmine/performance_tests/scattergl_test.js @@ -40,6 +40,20 @@ var tests = [{ n: 32000, mode: 'lines', nTraces: 1 }, { n: 64000, mode: 'lines', nTraces: 1 +}, { + n: 1000, mode: 'markers+lines', nTraces: 1 +}, { + n: 2000, mode: 'markers+lines', nTraces: 1 +}, { + n: 4000, mode: 'markers+lines', nTraces: 1 +}, { + n: 8000, mode: 'markers+lines', nTraces: 1 +}, { + n: 16000, mode: 'markers+lines', nTraces: 1 +}, { + n: 32000, mode: 'markers+lines', nTraces: 1 +}, { + n: 64000, mode: 'markers+lines', nTraces: 1 }, { n: 1000, mode: 'markers', nTraces: 10 }, { @@ -68,6 +82,20 @@ var tests = [{ n: 32000, mode: 'lines', nTraces: 10 }, { n: 64000, mode: 'lines', nTraces: 10 +}, { + n: 1000, mode: 'markers+lines', nTraces: 10 +}, { + n: 2000, mode: 'markers+lines', nTraces: 10 +}, { + n: 4000, mode: 'markers+lines', nTraces: 10 +}, { + n: 8000, mode: 'markers+lines', nTraces: 10 +}, { + n: 16000, mode: 'markers+lines', nTraces: 10 +}, { + n: 32000, mode: 'markers+lines', nTraces: 10 +}, { + n: 64000, mode: 'markers+lines', nTraces: 10 }, { n: 1000, mode: 'markers', nTraces: 100 }, { @@ -96,6 +124,20 @@ var tests = [{ n: 32000, mode: 'lines', nTraces: 100 }, { n: 64000, mode: 'lines', nTraces: 100 +}, { + n: 1000, mode: 'markers+lines', nTraces: 100 +}, { + n: 2000, mode: 'markers+lines', nTraces: 100 +}, { + n: 4000, mode: 'markers+lines', nTraces: 100 +}, { + n: 8000, mode: 'markers+lines', nTraces: 100 +}, { + n: 16000, mode: 'markers+lines', nTraces: 100 +}, { + n: 32000, mode: 'markers+lines', nTraces: 100 +}, { + n: 64000, mode: 'markers+lines', nTraces: 100 }]; tests.forEach(function(spec, index) { From a4aa4367a6b062d826b68637e74b209d797fe639 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 14:16:59 -0400 Subject: [PATCH 24/46] use normal arrays in tests --- test/jasmine/performance_tests/contour_test.js | 6 +++--- test/jasmine/performance_tests/heatmap_test.js | 6 +++--- test/jasmine/performance_tests/image_test.js | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/jasmine/performance_tests/contour_test.js b/test/jasmine/performance_tests/contour_test.js index c38e1722b02..52f69df411c 100644 --- a/test/jasmine/performance_tests/contour_test.js +++ b/test/jasmine/performance_tests/contour_test.js @@ -37,11 +37,11 @@ tests.forEach(function(spec, index) { var B = spec.ny; spec.n = A * B; - var x = Uint16Array.from({ length: A }, (_, i) => i); - var y = Uint16Array.from({ length: B }, (_, i) => i); + var x = Array.from({ length: A }, (_, i) => i); + var y = Array.from({ length: B }, (_, i) => i); var z = []; for(var k = 0; k < B ; k++) { - z[k] = Float64Array.from({ length: A }, (_, i) => k * Math.cos(Math.sqrt(i))); + z[k] = Array.from({ length: A }, (_, i) => k * Math.cos(Math.sqrt(i))); } var mock = { diff --git a/test/jasmine/performance_tests/heatmap_test.js b/test/jasmine/performance_tests/heatmap_test.js index 0c0ae151e77..a948bf8fb73 100644 --- a/test/jasmine/performance_tests/heatmap_test.js +++ b/test/jasmine/performance_tests/heatmap_test.js @@ -37,11 +37,11 @@ tests.forEach(function(spec, index) { var B = spec.ny; spec.n = A * B; - var x = Uint16Array.from({ length: A }, (_, i) => i); - var y = Uint16Array.from({ length: B }, (_, i) => i); + var x = Array.from({ length: A }, (_, i) => i); + var y = Array.from({ length: B }, (_, i) => i); var z = []; for(var k = 0; k < B ; k++) { - z[k] = Float64Array.from({ length: A }, (_, i) => k * Math.cos(Math.sqrt(i))); + z[k] = Array.from({ length: A }, (_, i) => k * Math.cos(Math.sqrt(i))); } var mock = { diff --git a/test/jasmine/performance_tests/image_test.js b/test/jasmine/performance_tests/image_test.js index 39ddf256477..4dfaf7beb0a 100644 --- a/test/jasmine/performance_tests/image_test.js +++ b/test/jasmine/performance_tests/image_test.js @@ -40,8 +40,8 @@ tests.forEach(function(spec, index) { var B = spec.ny; spec.n = A * B; - var x = Uint16Array.from({ length: A }, (_, i) => i); - var y = Uint16Array.from({ length: B }, (_, i) => i); + var x = Array.from({ length: A }, (_, i) => i); + var y = Array.from({ length: B }, (_, i) => i); var z = []; for(var k = 0; k < B ; k++) { z[k] = []; From 98252d41ac104c21eb0ec63ad946d286ce6d312f Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 14:31:18 -0400 Subject: [PATCH 25/46] add scattergeo tests --- .../performance_tests/scattergeo_test.js | 204 ++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 test/jasmine/performance_tests/scattergeo_test.js diff --git a/test/jasmine/performance_tests/scattergeo_test.js b/test/jasmine/performance_tests/scattergeo_test.js new file mode 100644 index 00000000000..d0db3c5cedc --- /dev/null +++ b/test/jasmine/performance_tests/scattergeo_test.js @@ -0,0 +1,204 @@ +var createGraphDiv = require('../assets/create_graph_div'); +var delay = require('../assets/delay'); +var Plotly = require('../../../lib/core'); +var PlotlyScattergeo = require('../../../lib/scattergeo'); +var downloadCSV = require('./assets/post_process').downloadCSV; +var nSamples = require('./assets/constants').nSamples; + +Plotly.register(PlotlyScattergeo); + +var gd = createGraphDiv(); + +const samples = Array.from({ length: nSamples }, (_, i) => i); +const nTimes = samples.length - 1; + +var tests = [{ + n: 1000, mode: 'markers', nTraces: 1 +}, { + n: 2000, mode: 'markers', nTraces: 1 +}, { + n: 4000, mode: 'markers', nTraces: 1 +}, { + n: 8000, mode: 'markers', nTraces: 1 +}, { + n: 16000, mode: 'markers', nTraces: 1 +}, { + n: 32000, mode: 'markers', nTraces: 1 +}, { + n: 64000, mode: 'markers', nTraces: 1 +}, { + n: 1000, mode: 'lines', nTraces: 1 +}, { + n: 2000, mode: 'lines', nTraces: 1 +}, { + n: 4000, mode: 'lines', nTraces: 1 +}, { + n: 8000, mode: 'lines', nTraces: 1 +}, { + n: 16000, mode: 'lines', nTraces: 1 +}, { + n: 32000, mode: 'lines', nTraces: 1 +}, { + n: 64000, mode: 'lines', nTraces: 1 +}, { + n: 1000, mode: 'markers+lines', nTraces: 1 +}, { + n: 2000, mode: 'markers+lines', nTraces: 1 +}, { + n: 4000, mode: 'markers+lines', nTraces: 1 +}, { + n: 8000, mode: 'markers+lines', nTraces: 1 +}, { + n: 16000, mode: 'markers+lines', nTraces: 1 +}, { + n: 32000, mode: 'markers+lines', nTraces: 1 +}, { + n: 64000, mode: 'markers+lines', nTraces: 1 +}, { + n: 1000, mode: 'markers', nTraces: 10 +}, { + n: 2000, mode: 'markers', nTraces: 10 +}, { + n: 4000, mode: 'markers', nTraces: 10 +}, { + n: 8000, mode: 'markers', nTraces: 10 +}, { + n: 16000, mode: 'markers', nTraces: 10 +}, { + n: 32000, mode: 'markers', nTraces: 10 +}, { + n: 64000, mode: 'markers', nTraces: 10 +}, { + n: 1000, mode: 'lines', nTraces: 10 +}, { + n: 2000, mode: 'lines', nTraces: 10 +}, { + n: 4000, mode: 'lines', nTraces: 10 +}, { + n: 8000, mode: 'lines', nTraces: 10 +}, { + n: 16000, mode: 'lines', nTraces: 10 +}, { + n: 32000, mode: 'lines', nTraces: 10 +}, { + n: 64000, mode: 'lines', nTraces: 10 +}, { + n: 1000, mode: 'markers+lines', nTraces: 10 +}, { + n: 2000, mode: 'markers+lines', nTraces: 10 +}, { + n: 4000, mode: 'markers+lines', nTraces: 10 +}, { + n: 8000, mode: 'markers+lines', nTraces: 10 +}, { + n: 16000, mode: 'markers+lines', nTraces: 10 +}, { + n: 32000, mode: 'markers+lines', nTraces: 10 +}, { + n: 64000, mode: 'markers+lines', nTraces: 10 +}, { + n: 1000, mode: 'markers', nTraces: 100 +}, { + n: 2000, mode: 'markers', nTraces: 100 +}, { + n: 4000, mode: 'markers', nTraces: 100 +}, { + n: 8000, mode: 'markers', nTraces: 100 +}, { + n: 16000, mode: 'markers', nTraces: 100 +}, { + n: 32000, mode: 'markers', nTraces: 100 +}, { + n: 64000, mode: 'markers', nTraces: 100 +}, { + n: 1000, mode: 'lines', nTraces: 100 +}, { + n: 2000, mode: 'lines', nTraces: 100 +}, { + n: 4000, mode: 'lines', nTraces: 100 +}, { + n: 8000, mode: 'lines', nTraces: 100 +}, { + n: 16000, mode: 'lines', nTraces: 100 +}, { + n: 32000, mode: 'lines', nTraces: 100 +}, { + n: 64000, mode: 'lines', nTraces: 100 +}, { + n: 1000, mode: 'markers+lines', nTraces: 100 +}, { + n: 2000, mode: 'markers+lines', nTraces: 100 +}, { + n: 4000, mode: 'markers+lines', nTraces: 100 +}, { + n: 8000, mode: 'markers+lines', nTraces: 100 +}, { + n: 16000, mode: 'markers+lines', nTraces: 100 +}, { + n: 32000, mode: 'markers+lines', nTraces: 100 +}, { + n: 64000, mode: 'markers+lines', nTraces: 100 +}]; + +tests.forEach(function(spec, index) { + describe('Performance test ' + spec.nTraces + 'scattergeo | size:' + spec.n + ' | mode: ' + spec.mode, function() { + 'use strict'; + + var startTime, endTime; + + beforeEach(function(done) { + var y = Array.from({ length: spec.n }, (_, i) => 0.001 * i * Math.cos(Math.sqrt(i))); + + var data = []; + var nPerTrace = Math.floor(spec.n / spec.nTraces); + for(var k = 0; k < spec.nTraces; k++) { + data.push({ + type: 'scattergeo', + mode: spec.mode, + lat: y.slice(k * nPerTrace, (k + 1) * nPerTrace), + lon: Array.from({ length: nPerTrace }, (_, i) => -180 + 0.005 * (i + k * nPerTrace)) + }); + } + + var mock = { + data: data, + layout: { + showlegend: false, + width: 900, + height: 400 + } + }; + + startTime = performance.now(); + + // Wait for actual rendering to complete + requestAnimationFrame(function() { + requestAnimationFrame(function() { + endTime = performance.now(); + done(); + }); + }); + + Plotly.newPlot(gd, mock); + }); + + afterEach(function(done) { + delay(100)().then(done); + }); + + samples.forEach(function(t) { + it('should graph scattergeo traces | turn: ' + t, function() { + var delta = endTime - startTime; + + if(t === 0) { + tests[index].raw = []; + } + tests[index].raw[t] = delta; + + if(t === nTimes && index === tests.length - 1) { + downloadCSV('scattergeo', tests); + } + }); + }); + }); +}); From 3134b6168de626f4115f13deeaf0ec04beb90a57 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 14:33:19 -0400 Subject: [PATCH 26/46] set nSamples to 4 --- test/jasmine/performance_tests/assets/constants.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jasmine/performance_tests/assets/constants.js b/test/jasmine/performance_tests/assets/constants.js index 53fb3438b71..0fe113801ce 100644 --- a/test/jasmine/performance_tests/assets/constants.js +++ b/test/jasmine/performance_tests/assets/constants.js @@ -1,5 +1,5 @@ 'use strict'; module.exports = { - nSamples: 1 + nSamples: 4 }; From d4f3af2eb36f76c816529eabb02f2dafc103c288 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 14:57:05 -0400 Subject: [PATCH 27/46] format test messages --- test/jasmine/performance_tests/bar_test.js | 2 +- test/jasmine/performance_tests/box_test.js | 2 +- test/jasmine/performance_tests/histogram_test.js | 2 +- test/jasmine/performance_tests/scatter_test.js | 2 +- test/jasmine/performance_tests/scattergeo_test.js | 2 +- test/jasmine/performance_tests/scattergl_test.js | 2 +- test/jasmine/performance_tests/violin_test.js | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/jasmine/performance_tests/bar_test.js b/test/jasmine/performance_tests/bar_test.js index 9edca9ec1b9..c66591a0cde 100644 --- a/test/jasmine/performance_tests/bar_test.js +++ b/test/jasmine/performance_tests/bar_test.js @@ -100,7 +100,7 @@ var tests = [{ }]; tests.forEach(function(spec, index) { - describe('Performance test ' + spec.nTraces + 'bar | size:' + spec.n + ' | mode: ' + spec.mode, function() { + describe('Performance test ' + spec.nTraces + ' bar | size:' + spec.n + ' | mode: ' + spec.mode, function() { 'use strict'; var startTime, endTime; diff --git a/test/jasmine/performance_tests/box_test.js b/test/jasmine/performance_tests/box_test.js index e5a7bae6678..37579a579be 100644 --- a/test/jasmine/performance_tests/box_test.js +++ b/test/jasmine/performance_tests/box_test.js @@ -100,7 +100,7 @@ var tests = [{ }]; tests.forEach(function(spec, index) { - describe('Performance test ' + spec.nTraces + 'box | size:' + spec.n + ' | mode: ' + spec.mode, function() { + describe('Performance test ' + spec.nTraces + ' box | size:' + spec.n + ' | mode: ' + spec.mode, function() { 'use strict'; var startTime, endTime; diff --git a/test/jasmine/performance_tests/histogram_test.js b/test/jasmine/performance_tests/histogram_test.js index ccf3e75782f..ecb114119fd 100644 --- a/test/jasmine/performance_tests/histogram_test.js +++ b/test/jasmine/performance_tests/histogram_test.js @@ -100,7 +100,7 @@ var tests = [{ }]; tests.forEach(function(spec, index) { - describe('Performance test ' + spec.nTraces + 'histogram | size:' + spec.n + ' | mode: ' + spec.mode, function() { + describe('Performance test ' + spec.nTraces + ' histogram | size:' + spec.n + ' | mode: ' + spec.mode, function() { 'use strict'; var startTime, endTime; diff --git a/test/jasmine/performance_tests/scatter_test.js b/test/jasmine/performance_tests/scatter_test.js index 001f8125b16..382abeec502 100644 --- a/test/jasmine/performance_tests/scatter_test.js +++ b/test/jasmine/performance_tests/scatter_test.js @@ -139,7 +139,7 @@ var tests = [{ }]; tests.forEach(function(spec, index) { - describe('Performance test ' + spec.nTraces + 'scatter | size:' + spec.n + ' | mode: ' + spec.mode, function() { + describe('Performance test ' + spec.nTraces + ' scatter | size:' + spec.n + ' | mode: ' + spec.mode, function() { 'use strict'; var startTime, endTime; diff --git a/test/jasmine/performance_tests/scattergeo_test.js b/test/jasmine/performance_tests/scattergeo_test.js index d0db3c5cedc..24314337809 100644 --- a/test/jasmine/performance_tests/scattergeo_test.js +++ b/test/jasmine/performance_tests/scattergeo_test.js @@ -141,7 +141,7 @@ var tests = [{ }]; tests.forEach(function(spec, index) { - describe('Performance test ' + spec.nTraces + 'scattergeo | size:' + spec.n + ' | mode: ' + spec.mode, function() { + describe('Performance test ' + spec.nTraces + ' scattergeo | size:' + spec.n + ' | mode: ' + spec.mode, function() { 'use strict'; var startTime, endTime; diff --git a/test/jasmine/performance_tests/scattergl_test.js b/test/jasmine/performance_tests/scattergl_test.js index f415efd58c2..1a38f4870c9 100644 --- a/test/jasmine/performance_tests/scattergl_test.js +++ b/test/jasmine/performance_tests/scattergl_test.js @@ -141,7 +141,7 @@ var tests = [{ }]; tests.forEach(function(spec, index) { - describe('Performance test ' + spec.nTraces + 'scattergl | size:' + spec.n + ' | mode: ' + spec.mode, function() { + describe('Performance test ' + spec.nTraces + ' scattergl | size:' + spec.n + ' | mode: ' + spec.mode, function() { 'use strict'; var startTime, endTime; diff --git a/test/jasmine/performance_tests/violin_test.js b/test/jasmine/performance_tests/violin_test.js index 75a779d38d4..06c0f6c62c2 100644 --- a/test/jasmine/performance_tests/violin_test.js +++ b/test/jasmine/performance_tests/violin_test.js @@ -100,7 +100,7 @@ var tests = [{ }]; tests.forEach(function(spec, index) { - describe('Performance test ' + spec.nTraces + 'violin | size:' + spec.n + ' | mode: ' + spec.mode, function() { + describe('Performance test ' + spec.nTraces + ' violin | size:' + spec.n + ' | mode: ' + spec.mode, function() { 'use strict'; var startTime, endTime; From 5d30519eac891e2466076fcf20f209c142ffbaf2 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 16:16:54 -0400 Subject: [PATCH 28/46] revisit test descriptions --- test/jasmine/performance_tests/bar_test.js | 97 ++---------- test/jasmine/performance_tests/box_test.js | 97 ++---------- .../jasmine/performance_tests/contour_test.js | 26 ++-- .../jasmine/performance_tests/heatmap_test.js | 26 ++-- .../performance_tests/histogram_test.js | 97 ++---------- test/jasmine/performance_tests/image_test.js | 29 ++-- .../jasmine/performance_tests/scatter_test.js | 139 ++---------------- .../performance_tests/scattergeo_test.js | 139 ++---------------- .../performance_tests/scattergl_test.js | 139 ++---------------- test/jasmine/performance_tests/violin_test.js | 97 ++---------- 10 files changed, 114 insertions(+), 772 deletions(-) diff --git a/test/jasmine/performance_tests/bar_test.js b/test/jasmine/performance_tests/bar_test.js index c66591a0cde..9bb3cbe911e 100644 --- a/test/jasmine/performance_tests/bar_test.js +++ b/test/jasmine/performance_tests/bar_test.js @@ -13,91 +13,18 @@ var gd = createGraphDiv(); const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; -var tests = [{ - n: 1000, mode: 'group', nTraces: 1 -}, { - n: 2000, mode: 'group', nTraces: 1 -}, { - n: 4000, mode: 'group', nTraces: 1 -}, { - n: 8000, mode: 'group', nTraces: 1 -}, { - n: 16000, mode: 'group', nTraces: 1 -}, { - n: 32000, mode: 'group', nTraces: 1 -}, { - n: 64000, mode: 'group', nTraces: 1 -}, { - n: 1000, mode: 'stack', nTraces: 1 -}, { - n: 2000, mode: 'stack', nTraces: 1 -}, { - n: 4000, mode: 'stack', nTraces: 1 -}, { - n: 8000, mode: 'stack', nTraces: 1 -}, { - n: 16000, mode: 'stack', nTraces: 1 -}, { - n: 32000, mode: 'stack', nTraces: 1 -}, { - n: 64000, mode: 'stack', nTraces: 1 -}, { - n: 1000, mode: 'group', nTraces: 10 -}, { - n: 2000, mode: 'group', nTraces: 10 -}, { - n: 4000, mode: 'group', nTraces: 10 -}, { - n: 8000, mode: 'group', nTraces: 10 -}, { - n: 16000, mode: 'group', nTraces: 10 -}, { - n: 32000, mode: 'group', nTraces: 10 -}, { - n: 64000, mode: 'group', nTraces: 10 -}, { - n: 1000, mode: 'stack', nTraces: 10 -}, { - n: 2000, mode: 'stack', nTraces: 10 -}, { - n: 4000, mode: 'stack', nTraces: 10 -}, { - n: 8000, mode: 'stack', nTraces: 10 -}, { - n: 16000, mode: 'stack', nTraces: 10 -}, { - n: 32000, mode: 'stack', nTraces: 10 -}, { - n: 64000, mode: 'stack', nTraces: 10 -}, { - n: 1000, mode: 'group', nTraces: 100 -}, { - n: 2000, mode: 'group', nTraces: 100 -}, { - n: 4000, mode: 'group', nTraces: 100 -}, { - n: 8000, mode: 'group', nTraces: 100 -}, { - n: 16000, mode: 'group', nTraces: 100 -}, { - n: 32000, mode: 'group', nTraces: 100 -}, { - n: 64000, mode: 'group', nTraces: 100 -}, { - n: 1000, mode: 'stack', nTraces: 100 -}, { - n: 2000, mode: 'stack', nTraces: 100 -}, { - n: 4000, mode: 'stack', nTraces: 100 -}, { - n: 8000, mode: 'stack', nTraces: 100 -}, { - n: 16000, mode: 'stack', nTraces: 100 -}, { - n: 32000, mode: 'stack', nTraces: 100 -}, { - n: 64000, mode: 'stack', nTraces: 100 -}]; +var tests = []; +for(let mode of ['group', 'stack']) { + for(let nTraces of [1, 10, 100]) { + for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { + tests.push({ + n:n, + mode: mode, + nTraces: nTraces + }); + } + } +} tests.forEach(function(spec, index) { describe('Performance test ' + spec.nTraces + ' bar | size:' + spec.n + ' | mode: ' + spec.mode, function() { diff --git a/test/jasmine/performance_tests/box_test.js b/test/jasmine/performance_tests/box_test.js index 37579a579be..f9361df1524 100644 --- a/test/jasmine/performance_tests/box_test.js +++ b/test/jasmine/performance_tests/box_test.js @@ -13,91 +13,18 @@ var gd = createGraphDiv(); const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; -var tests = [{ - n: 1000, mode: 'no points', nTraces: 1 -}, { - n: 2000, mode: 'no points', nTraces: 1 -}, { - n: 4000, mode: 'no points', nTraces: 1 -}, { - n: 8000, mode: 'no points', nTraces: 1 -}, { - n: 16000, mode: 'no points', nTraces: 1 -}, { - n: 32000, mode: 'no points', nTraces: 1 -}, { - n: 64000, mode: 'no points', nTraces: 1 -}, { - n: 1000, mode: 'all points', nTraces: 1 -}, { - n: 2000, mode: 'all points', nTraces: 1 -}, { - n: 4000, mode: 'all points', nTraces: 1 -}, { - n: 8000, mode: 'all points', nTraces: 1 -}, { - n: 16000, mode: 'all points', nTraces: 1 -}, { - n: 32000, mode: 'all points', nTraces: 1 -}, { - n: 64000, mode: 'all points', nTraces: 1 -}, { - n: 1000, mode: 'no points', nTraces: 10 -}, { - n: 2000, mode: 'no points', nTraces: 10 -}, { - n: 4000, mode: 'no points', nTraces: 10 -}, { - n: 8000, mode: 'no points', nTraces: 10 -}, { - n: 16000, mode: 'no points', nTraces: 10 -}, { - n: 32000, mode: 'no points', nTraces: 10 -}, { - n: 64000, mode: 'no points', nTraces: 10 -}, { - n: 1000, mode: 'all points', nTraces: 10 -}, { - n: 2000, mode: 'all points', nTraces: 10 -}, { - n: 4000, mode: 'all points', nTraces: 10 -}, { - n: 8000, mode: 'all points', nTraces: 10 -}, { - n: 16000, mode: 'all points', nTraces: 10 -}, { - n: 32000, mode: 'all points', nTraces: 10 -}, { - n: 64000, mode: 'all points', nTraces: 10 -}, { - n: 1000, mode: 'no points', nTraces: 100 -}, { - n: 2000, mode: 'no points', nTraces: 100 -}, { - n: 4000, mode: 'no points', nTraces: 100 -}, { - n: 8000, mode: 'no points', nTraces: 100 -}, { - n: 16000, mode: 'no points', nTraces: 100 -}, { - n: 32000, mode: 'no points', nTraces: 100 -}, { - n: 64000, mode: 'no points', nTraces: 100 -}, { - n: 1000, mode: 'all points', nTraces: 100 -}, { - n: 2000, mode: 'all points', nTraces: 100 -}, { - n: 4000, mode: 'all points', nTraces: 100 -}, { - n: 8000, mode: 'all points', nTraces: 100 -}, { - n: 16000, mode: 'all points', nTraces: 100 -}, { - n: 32000, mode: 'all points', nTraces: 100 -}, { - n: 64000, mode: 'all points', nTraces: 100 -}]; +var tests = []; +for(let mode of ['no points', 'all points']) { + for(let nTraces of [1, 10, 100]) { + for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { + tests.push({ + n:n, + mode: mode, + nTraces: nTraces + }); + } + } +} tests.forEach(function(spec, index) { describe('Performance test ' + spec.nTraces + ' box | size:' + spec.n + ' | mode: ' + spec.mode, function() { diff --git a/test/jasmine/performance_tests/contour_test.js b/test/jasmine/performance_tests/contour_test.js index 52f69df411c..2111fd9bd44 100644 --- a/test/jasmine/performance_tests/contour_test.js +++ b/test/jasmine/performance_tests/contour_test.js @@ -13,21 +13,16 @@ var gd = createGraphDiv(); const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; -var tests = [{ - nx: 50, ny: 20 -}, { - nx: 100, ny: 40 -}, { - nx: 200, ny: 80 -}, { - nx: 400, ny: 160 -}, { - nx: 800, ny: 320 -}, { - nx: 1600, ny: 640 -}, { - nx: 3200, ny: 1280 -}]; +var tests = []; +for(let m of [10, 20, 40, 80, 160, 320, 640]) { + let nx = 5 * m; + let ny = 2 * m; + tests.push({ + nx: nx, + ny: ny, + n: nx * ny, + }); +} tests.forEach(function(spec, index) { describe('Performance test contour | size:' + spec.nx + 'X' + spec.ny, function() { @@ -35,7 +30,6 @@ tests.forEach(function(spec, index) { var A = spec.nx; var B = spec.ny; - spec.n = A * B; var x = Array.from({ length: A }, (_, i) => i); var y = Array.from({ length: B }, (_, i) => i); diff --git a/test/jasmine/performance_tests/heatmap_test.js b/test/jasmine/performance_tests/heatmap_test.js index a948bf8fb73..93d8ac8c16a 100644 --- a/test/jasmine/performance_tests/heatmap_test.js +++ b/test/jasmine/performance_tests/heatmap_test.js @@ -13,21 +13,16 @@ var gd = createGraphDiv(); const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; -var tests = [{ - nx: 50, ny: 20 -}, { - nx: 100, ny: 40 -}, { - nx: 200, ny: 80 -}, { - nx: 400, ny: 160 -}, { - nx: 800, ny: 320 -}, { - nx: 1600, ny: 640 -}, { - nx: 3200, ny: 1280 -}]; +var tests = []; +for(let m of [10, 20, 40, 80, 160, 320, 640]) { + let nx = 5 * m; + let ny = 2 * m; + tests.push({ + nx: nx, + ny: ny, + n: nx * ny, + }); +} tests.forEach(function(spec, index) { describe('Performance test heatmap | size:' + spec.nx + 'X' + spec.ny, function() { @@ -35,7 +30,6 @@ tests.forEach(function(spec, index) { var A = spec.nx; var B = spec.ny; - spec.n = A * B; var x = Array.from({ length: A }, (_, i) => i); var y = Array.from({ length: B }, (_, i) => i); diff --git a/test/jasmine/performance_tests/histogram_test.js b/test/jasmine/performance_tests/histogram_test.js index ecb114119fd..66a03e613f7 100644 --- a/test/jasmine/performance_tests/histogram_test.js +++ b/test/jasmine/performance_tests/histogram_test.js @@ -13,91 +13,18 @@ var gd = createGraphDiv(); const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; -var tests = [{ - n: 1000, mode: 'group', nTraces: 1 -}, { - n: 2000, mode: 'group', nTraces: 1 -}, { - n: 4000, mode: 'group', nTraces: 1 -}, { - n: 8000, mode: 'group', nTraces: 1 -}, { - n: 16000, mode: 'group', nTraces: 1 -}, { - n: 32000, mode: 'group', nTraces: 1 -}, { - n: 64000, mode: 'group', nTraces: 1 -}, { - n: 1000, mode: 'stack', nTraces: 1 -}, { - n: 2000, mode: 'stack', nTraces: 1 -}, { - n: 4000, mode: 'stack', nTraces: 1 -}, { - n: 8000, mode: 'stack', nTraces: 1 -}, { - n: 16000, mode: 'stack', nTraces: 1 -}, { - n: 32000, mode: 'stack', nTraces: 1 -}, { - n: 64000, mode: 'stack', nTraces: 1 -}, { - n: 1000, mode: 'group', nTraces: 10 -}, { - n: 2000, mode: 'group', nTraces: 10 -}, { - n: 4000, mode: 'group', nTraces: 10 -}, { - n: 8000, mode: 'group', nTraces: 10 -}, { - n: 16000, mode: 'group', nTraces: 10 -}, { - n: 32000, mode: 'group', nTraces: 10 -}, { - n: 64000, mode: 'group', nTraces: 10 -}, { - n: 1000, mode: 'stack', nTraces: 10 -}, { - n: 2000, mode: 'stack', nTraces: 10 -}, { - n: 4000, mode: 'stack', nTraces: 10 -}, { - n: 8000, mode: 'stack', nTraces: 10 -}, { - n: 16000, mode: 'stack', nTraces: 10 -}, { - n: 32000, mode: 'stack', nTraces: 10 -}, { - n: 64000, mode: 'stack', nTraces: 10 -}, { - n: 1000, mode: 'group', nTraces: 100 -}, { - n: 2000, mode: 'group', nTraces: 100 -}, { - n: 4000, mode: 'group', nTraces: 100 -}, { - n: 8000, mode: 'group', nTraces: 100 -}, { - n: 16000, mode: 'group', nTraces: 100 -}, { - n: 32000, mode: 'group', nTraces: 100 -}, { - n: 64000, mode: 'group', nTraces: 100 -}, { - n: 1000, mode: 'stack', nTraces: 100 -}, { - n: 2000, mode: 'stack', nTraces: 100 -}, { - n: 4000, mode: 'stack', nTraces: 100 -}, { - n: 8000, mode: 'stack', nTraces: 100 -}, { - n: 16000, mode: 'stack', nTraces: 100 -}, { - n: 32000, mode: 'stack', nTraces: 100 -}, { - n: 64000, mode: 'stack', nTraces: 100 -}]; +var tests = []; +for(let mode of ['group', 'stack']) { + for(let nTraces of [1, 10, 100]) { + for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { + tests.push({ + n:n, + mode: mode, + nTraces: nTraces + }); + } + } +} tests.forEach(function(spec, index) { describe('Performance test ' + spec.nTraces + ' histogram | size:' + spec.n + ' | mode: ' + spec.mode, function() { diff --git a/test/jasmine/performance_tests/image_test.js b/test/jasmine/performance_tests/image_test.js index 4dfaf7beb0a..3e87eec172e 100644 --- a/test/jasmine/performance_tests/image_test.js +++ b/test/jasmine/performance_tests/image_test.js @@ -13,32 +13,23 @@ var gd = createGraphDiv(); const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; -var tests = [{ - nx: 50, ny: 20 -}, { - nx: 100, ny: 40 -}, { - nx: 200, ny: 80 -}, { - nx: 400, ny: 160 -}, { - nx: 800, ny: 320 -}, { - nx: 1600, ny: 640 -}, { - nx: 3200, ny: 1280 -}]; +var tests = []; +for(let m of [10, 20, 40, 80, 160, 320, 640]) { + let nx = 5 * m; + let ny = 2 * m; + tests.push({ + nx: nx, + ny: ny, + n: nx * ny, + }); +} tests.forEach(function(spec, index) { describe('Performance test image | size:' + spec.nx + 'X' + spec.ny, function() { 'use strict'; - const samples = Array.from({ length: nSamples }, (_, i) => i); - const nTimes = samples.length - 1; - var A = spec.nx; var B = spec.ny; - spec.n = A * B; var x = Array.from({ length: A }, (_, i) => i); var y = Array.from({ length: B }, (_, i) => i); diff --git a/test/jasmine/performance_tests/scatter_test.js b/test/jasmine/performance_tests/scatter_test.js index 382abeec502..97b21112856 100644 --- a/test/jasmine/performance_tests/scatter_test.js +++ b/test/jasmine/performance_tests/scatter_test.js @@ -10,133 +10,18 @@ var gd = createGraphDiv(); const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; -var tests = [{ - n: 1000, mode: 'markers', nTraces: 1 -}, { - n: 2000, mode: 'markers', nTraces: 1 -}, { - n: 4000, mode: 'markers', nTraces: 1 -}, { - n: 8000, mode: 'markers', nTraces: 1 -}, { - n: 16000, mode: 'markers', nTraces: 1 -}, { - n: 32000, mode: 'markers', nTraces: 1 -}, { - n: 64000, mode: 'markers', nTraces: 1 -}, { - n: 1000, mode: 'lines', nTraces: 1 -}, { - n: 2000, mode: 'lines', nTraces: 1 -}, { - n: 4000, mode: 'lines', nTraces: 1 -}, { - n: 8000, mode: 'lines', nTraces: 1 -}, { - n: 16000, mode: 'lines', nTraces: 1 -}, { - n: 32000, mode: 'lines', nTraces: 1 -}, { - n: 64000, mode: 'lines', nTraces: 1 -}, { - n: 1000, mode: 'markers+lines', nTraces: 1 -}, { - n: 2000, mode: 'markers+lines', nTraces: 1 -}, { - n: 4000, mode: 'markers+lines', nTraces: 1 -}, { - n: 8000, mode: 'markers+lines', nTraces: 1 -}, { - n: 16000, mode: 'markers+lines', nTraces: 1 -}, { - n: 32000, mode: 'markers+lines', nTraces: 1 -}, { - n: 64000, mode: 'markers+lines', nTraces: 1 -}, { - n: 1000, mode: 'markers', nTraces: 10 -}, { - n: 2000, mode: 'markers', nTraces: 10 -}, { - n: 4000, mode: 'markers', nTraces: 10 -}, { - n: 8000, mode: 'markers', nTraces: 10 -}, { - n: 16000, mode: 'markers', nTraces: 10 -}, { - n: 32000, mode: 'markers', nTraces: 10 -}, { - n: 64000, mode: 'markers', nTraces: 10 -}, { - n: 1000, mode: 'lines', nTraces: 10 -}, { - n: 2000, mode: 'lines', nTraces: 10 -}, { - n: 4000, mode: 'lines', nTraces: 10 -}, { - n: 8000, mode: 'lines', nTraces: 10 -}, { - n: 16000, mode: 'lines', nTraces: 10 -}, { - n: 32000, mode: 'lines', nTraces: 10 -}, { - n: 64000, mode: 'lines', nTraces: 10 -}, { - n: 1000, mode: 'markers+lines', nTraces: 10 -}, { - n: 2000, mode: 'markers+lines', nTraces: 10 -}, { - n: 4000, mode: 'markers+lines', nTraces: 10 -}, { - n: 8000, mode: 'markers+lines', nTraces: 10 -}, { - n: 16000, mode: 'markers+lines', nTraces: 10 -}, { - n: 32000, mode: 'markers+lines', nTraces: 10 -}, { - n: 64000, mode: 'markers+lines', nTraces: 10 -}, { - n: 1000, mode: 'markers', nTraces: 100 -}, { - n: 2000, mode: 'markers', nTraces: 100 -}, { - n: 4000, mode: 'markers', nTraces: 100 -}, { - n: 8000, mode: 'markers', nTraces: 100 -}, { - n: 16000, mode: 'markers', nTraces: 100 -}, { - n: 32000, mode: 'markers', nTraces: 100 -}, { - n: 64000, mode: 'markers', nTraces: 100 -}, { - n: 1000, mode: 'lines', nTraces: 100 -}, { - n: 2000, mode: 'lines', nTraces: 100 -}, { - n: 4000, mode: 'lines', nTraces: 100 -}, { - n: 8000, mode: 'lines', nTraces: 100 -}, { - n: 16000, mode: 'lines', nTraces: 100 -}, { - n: 32000, mode: 'lines', nTraces: 100 -}, { - n: 64000, mode: 'lines', nTraces: 100 -}, { - n: 1000, mode: 'markers+lines', nTraces: 100 -}, { - n: 2000, mode: 'markers+lines', nTraces: 100 -}, { - n: 4000, mode: 'markers+lines', nTraces: 100 -}, { - n: 8000, mode: 'markers+lines', nTraces: 100 -}, { - n: 16000, mode: 'markers+lines', nTraces: 100 -}, { - n: 32000, mode: 'markers+lines', nTraces: 100 -}, { - n: 64000, mode: 'markers+lines', nTraces: 100 -}]; +var tests = []; +for(let mode of ['markers', 'lines', 'markers+lines']) { + for(let nTraces of [1, 10, 100]) { + for(let n of [1000, 2000, 4000, 8000, 16000, 32000, 64000]) { + tests.push({ + n:n, + mode: mode, + nTraces: nTraces + }); + } + } +} tests.forEach(function(spec, index) { describe('Performance test ' + spec.nTraces + ' scatter | size:' + spec.n + ' | mode: ' + spec.mode, function() { diff --git a/test/jasmine/performance_tests/scattergeo_test.js b/test/jasmine/performance_tests/scattergeo_test.js index 24314337809..8c456201408 100644 --- a/test/jasmine/performance_tests/scattergeo_test.js +++ b/test/jasmine/performance_tests/scattergeo_test.js @@ -12,133 +12,18 @@ var gd = createGraphDiv(); const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; -var tests = [{ - n: 1000, mode: 'markers', nTraces: 1 -}, { - n: 2000, mode: 'markers', nTraces: 1 -}, { - n: 4000, mode: 'markers', nTraces: 1 -}, { - n: 8000, mode: 'markers', nTraces: 1 -}, { - n: 16000, mode: 'markers', nTraces: 1 -}, { - n: 32000, mode: 'markers', nTraces: 1 -}, { - n: 64000, mode: 'markers', nTraces: 1 -}, { - n: 1000, mode: 'lines', nTraces: 1 -}, { - n: 2000, mode: 'lines', nTraces: 1 -}, { - n: 4000, mode: 'lines', nTraces: 1 -}, { - n: 8000, mode: 'lines', nTraces: 1 -}, { - n: 16000, mode: 'lines', nTraces: 1 -}, { - n: 32000, mode: 'lines', nTraces: 1 -}, { - n: 64000, mode: 'lines', nTraces: 1 -}, { - n: 1000, mode: 'markers+lines', nTraces: 1 -}, { - n: 2000, mode: 'markers+lines', nTraces: 1 -}, { - n: 4000, mode: 'markers+lines', nTraces: 1 -}, { - n: 8000, mode: 'markers+lines', nTraces: 1 -}, { - n: 16000, mode: 'markers+lines', nTraces: 1 -}, { - n: 32000, mode: 'markers+lines', nTraces: 1 -}, { - n: 64000, mode: 'markers+lines', nTraces: 1 -}, { - n: 1000, mode: 'markers', nTraces: 10 -}, { - n: 2000, mode: 'markers', nTraces: 10 -}, { - n: 4000, mode: 'markers', nTraces: 10 -}, { - n: 8000, mode: 'markers', nTraces: 10 -}, { - n: 16000, mode: 'markers', nTraces: 10 -}, { - n: 32000, mode: 'markers', nTraces: 10 -}, { - n: 64000, mode: 'markers', nTraces: 10 -}, { - n: 1000, mode: 'lines', nTraces: 10 -}, { - n: 2000, mode: 'lines', nTraces: 10 -}, { - n: 4000, mode: 'lines', nTraces: 10 -}, { - n: 8000, mode: 'lines', nTraces: 10 -}, { - n: 16000, mode: 'lines', nTraces: 10 -}, { - n: 32000, mode: 'lines', nTraces: 10 -}, { - n: 64000, mode: 'lines', nTraces: 10 -}, { - n: 1000, mode: 'markers+lines', nTraces: 10 -}, { - n: 2000, mode: 'markers+lines', nTraces: 10 -}, { - n: 4000, mode: 'markers+lines', nTraces: 10 -}, { - n: 8000, mode: 'markers+lines', nTraces: 10 -}, { - n: 16000, mode: 'markers+lines', nTraces: 10 -}, { - n: 32000, mode: 'markers+lines', nTraces: 10 -}, { - n: 64000, mode: 'markers+lines', nTraces: 10 -}, { - n: 1000, mode: 'markers', nTraces: 100 -}, { - n: 2000, mode: 'markers', nTraces: 100 -}, { - n: 4000, mode: 'markers', nTraces: 100 -}, { - n: 8000, mode: 'markers', nTraces: 100 -}, { - n: 16000, mode: 'markers', nTraces: 100 -}, { - n: 32000, mode: 'markers', nTraces: 100 -}, { - n: 64000, mode: 'markers', nTraces: 100 -}, { - n: 1000, mode: 'lines', nTraces: 100 -}, { - n: 2000, mode: 'lines', nTraces: 100 -}, { - n: 4000, mode: 'lines', nTraces: 100 -}, { - n: 8000, mode: 'lines', nTraces: 100 -}, { - n: 16000, mode: 'lines', nTraces: 100 -}, { - n: 32000, mode: 'lines', nTraces: 100 -}, { - n: 64000, mode: 'lines', nTraces: 100 -}, { - n: 1000, mode: 'markers+lines', nTraces: 100 -}, { - n: 2000, mode: 'markers+lines', nTraces: 100 -}, { - n: 4000, mode: 'markers+lines', nTraces: 100 -}, { - n: 8000, mode: 'markers+lines', nTraces: 100 -}, { - n: 16000, mode: 'markers+lines', nTraces: 100 -}, { - n: 32000, mode: 'markers+lines', nTraces: 100 -}, { - n: 64000, mode: 'markers+lines', nTraces: 100 -}]; +var tests = []; +for(let mode of ['markers', 'lines', 'markers+lines']) { + for(let nTraces of [1, 10, 100]) { + for(let n of [1000, 2000, 4000, 8000, 16000, 32000, 64000]) { + tests.push({ + n:n, + mode: mode, + nTraces: nTraces + }); + } + } +} tests.forEach(function(spec, index) { describe('Performance test ' + spec.nTraces + ' scattergeo | size:' + spec.n + ' | mode: ' + spec.mode, function() { diff --git a/test/jasmine/performance_tests/scattergl_test.js b/test/jasmine/performance_tests/scattergl_test.js index 1a38f4870c9..05261f4e981 100644 --- a/test/jasmine/performance_tests/scattergl_test.js +++ b/test/jasmine/performance_tests/scattergl_test.js @@ -12,133 +12,18 @@ var gd = createGraphDiv(); const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; -var tests = [{ - n: 1000, mode: 'markers', nTraces: 1 -}, { - n: 2000, mode: 'markers', nTraces: 1 -}, { - n: 4000, mode: 'markers', nTraces: 1 -}, { - n: 8000, mode: 'markers', nTraces: 1 -}, { - n: 16000, mode: 'markers', nTraces: 1 -}, { - n: 32000, mode: 'markers', nTraces: 1 -}, { - n: 64000, mode: 'markers', nTraces: 1 -}, { - n: 1000, mode: 'lines', nTraces: 1 -}, { - n: 2000, mode: 'lines', nTraces: 1 -}, { - n: 4000, mode: 'lines', nTraces: 1 -}, { - n: 8000, mode: 'lines', nTraces: 1 -}, { - n: 16000, mode: 'lines', nTraces: 1 -}, { - n: 32000, mode: 'lines', nTraces: 1 -}, { - n: 64000, mode: 'lines', nTraces: 1 -}, { - n: 1000, mode: 'markers+lines', nTraces: 1 -}, { - n: 2000, mode: 'markers+lines', nTraces: 1 -}, { - n: 4000, mode: 'markers+lines', nTraces: 1 -}, { - n: 8000, mode: 'markers+lines', nTraces: 1 -}, { - n: 16000, mode: 'markers+lines', nTraces: 1 -}, { - n: 32000, mode: 'markers+lines', nTraces: 1 -}, { - n: 64000, mode: 'markers+lines', nTraces: 1 -}, { - n: 1000, mode: 'markers', nTraces: 10 -}, { - n: 2000, mode: 'markers', nTraces: 10 -}, { - n: 4000, mode: 'markers', nTraces: 10 -}, { - n: 8000, mode: 'markers', nTraces: 10 -}, { - n: 16000, mode: 'markers', nTraces: 10 -}, { - n: 32000, mode: 'markers', nTraces: 10 -}, { - n: 64000, mode: 'markers', nTraces: 10 -}, { - n: 1000, mode: 'lines', nTraces: 10 -}, { - n: 2000, mode: 'lines', nTraces: 10 -}, { - n: 4000, mode: 'lines', nTraces: 10 -}, { - n: 8000, mode: 'lines', nTraces: 10 -}, { - n: 16000, mode: 'lines', nTraces: 10 -}, { - n: 32000, mode: 'lines', nTraces: 10 -}, { - n: 64000, mode: 'lines', nTraces: 10 -}, { - n: 1000, mode: 'markers+lines', nTraces: 10 -}, { - n: 2000, mode: 'markers+lines', nTraces: 10 -}, { - n: 4000, mode: 'markers+lines', nTraces: 10 -}, { - n: 8000, mode: 'markers+lines', nTraces: 10 -}, { - n: 16000, mode: 'markers+lines', nTraces: 10 -}, { - n: 32000, mode: 'markers+lines', nTraces: 10 -}, { - n: 64000, mode: 'markers+lines', nTraces: 10 -}, { - n: 1000, mode: 'markers', nTraces: 100 -}, { - n: 2000, mode: 'markers', nTraces: 100 -}, { - n: 4000, mode: 'markers', nTraces: 100 -}, { - n: 8000, mode: 'markers', nTraces: 100 -}, { - n: 16000, mode: 'markers', nTraces: 100 -}, { - n: 32000, mode: 'markers', nTraces: 100 -}, { - n: 64000, mode: 'markers', nTraces: 100 -}, { - n: 1000, mode: 'lines', nTraces: 100 -}, { - n: 2000, mode: 'lines', nTraces: 100 -}, { - n: 4000, mode: 'lines', nTraces: 100 -}, { - n: 8000, mode: 'lines', nTraces: 100 -}, { - n: 16000, mode: 'lines', nTraces: 100 -}, { - n: 32000, mode: 'lines', nTraces: 100 -}, { - n: 64000, mode: 'lines', nTraces: 100 -}, { - n: 1000, mode: 'markers+lines', nTraces: 100 -}, { - n: 2000, mode: 'markers+lines', nTraces: 100 -}, { - n: 4000, mode: 'markers+lines', nTraces: 100 -}, { - n: 8000, mode: 'markers+lines', nTraces: 100 -}, { - n: 16000, mode: 'markers+lines', nTraces: 100 -}, { - n: 32000, mode: 'markers+lines', nTraces: 100 -}, { - n: 64000, mode: 'markers+lines', nTraces: 100 -}]; +var tests = []; +for(let mode of ['markers', 'lines', 'markers+lines']) { + for(let nTraces of [1, 10, 100]) { + for(let n of [1000, 2000, 4000, 8000, 16000, 32000, 64000]) { + tests.push({ + n:n, + mode: mode, + nTraces: nTraces + }); + } + } +} tests.forEach(function(spec, index) { describe('Performance test ' + spec.nTraces + ' scattergl | size:' + spec.n + ' | mode: ' + spec.mode, function() { diff --git a/test/jasmine/performance_tests/violin_test.js b/test/jasmine/performance_tests/violin_test.js index 06c0f6c62c2..2688490d2ac 100644 --- a/test/jasmine/performance_tests/violin_test.js +++ b/test/jasmine/performance_tests/violin_test.js @@ -13,91 +13,18 @@ var gd = createGraphDiv(); const samples = Array.from({ length: nSamples }, (_, i) => i); const nTimes = samples.length - 1; -var tests = [{ - n: 1000, mode: 'no points', nTraces: 1 -}, { - n: 2000, mode: 'no points', nTraces: 1 -}, { - n: 4000, mode: 'no points', nTraces: 1 -}, { - n: 8000, mode: 'no points', nTraces: 1 -}, { - n: 16000, mode: 'no points', nTraces: 1 -}, { - n: 32000, mode: 'no points', nTraces: 1 -}, { - n: 64000, mode: 'no points', nTraces: 1 -}, { - n: 1000, mode: 'all points', nTraces: 1 -}, { - n: 2000, mode: 'all points', nTraces: 1 -}, { - n: 4000, mode: 'all points', nTraces: 1 -}, { - n: 8000, mode: 'all points', nTraces: 1 -}, { - n: 16000, mode: 'all points', nTraces: 1 -}, { - n: 32000, mode: 'all points', nTraces: 1 -}, { - n: 64000, mode: 'all points', nTraces: 1 -}, { - n: 1000, mode: 'no points', nTraces: 10 -}, { - n: 2000, mode: 'no points', nTraces: 10 -}, { - n: 4000, mode: 'no points', nTraces: 10 -}, { - n: 8000, mode: 'no points', nTraces: 10 -}, { - n: 16000, mode: 'no points', nTraces: 10 -}, { - n: 32000, mode: 'no points', nTraces: 10 -}, { - n: 64000, mode: 'no points', nTraces: 10 -}, { - n: 1000, mode: 'all points', nTraces: 10 -}, { - n: 2000, mode: 'all points', nTraces: 10 -}, { - n: 4000, mode: 'all points', nTraces: 10 -}, { - n: 8000, mode: 'all points', nTraces: 10 -}, { - n: 16000, mode: 'all points', nTraces: 10 -}, { - n: 32000, mode: 'all points', nTraces: 10 -}, { - n: 64000, mode: 'all points', nTraces: 10 -}, { - n: 1000, mode: 'no points', nTraces: 100 -}, { - n: 2000, mode: 'no points', nTraces: 100 -}, { - n: 4000, mode: 'no points', nTraces: 100 -}, { - n: 8000, mode: 'no points', nTraces: 100 -}, { - n: 16000, mode: 'no points', nTraces: 100 -}, { - n: 32000, mode: 'no points', nTraces: 100 -}, { - n: 64000, mode: 'no points', nTraces: 100 -}, { - n: 1000, mode: 'all points', nTraces: 100 -}, { - n: 2000, mode: 'all points', nTraces: 100 -}, { - n: 4000, mode: 'all points', nTraces: 100 -}, { - n: 8000, mode: 'all points', nTraces: 100 -}, { - n: 16000, mode: 'all points', nTraces: 100 -}, { - n: 32000, mode: 'all points', nTraces: 100 -}, { - n: 64000, mode: 'all points', nTraces: 100 -}]; +var tests = []; +for(let mode of['no points', 'all points']) { + for(let nTraces of [1, 10, 100]) { + for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { + tests.push({ + n:n, + mode: mode, + nTraces: nTraces + }); + } + } +} tests.forEach(function(spec, index) { describe('Performance test ' + spec.nTraces + ' violin | size:' + spec.n + ' | mode: ' + spec.mode, function() { From c99d887e19bce7ea0694868eeea11aa6085ac9bb Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 23 Jun 2025 18:31:50 -0400 Subject: [PATCH 29/46] combine all tests --- .circleci/config.yml | 5 - test/jasmine/performance_tests/all_test.js | 317 ++++++++++++++++++ .../performance_tests/assets/post_process.js | 6 +- test/jasmine/performance_tests/bar_test.js | 92 ----- test/jasmine/performance_tests/box_test.js | 92 ----- .../jasmine/performance_tests/contour_test.js | 92 ----- .../jasmine/performance_tests/heatmap_test.js | 92 ----- .../performance_tests/histogram_test.js | 92 ----- test/jasmine/performance_tests/image_test.js | 99 ------ .../jasmine/performance_tests/scatter_test.js | 89 ----- .../performance_tests/scattergeo_test.js | 89 ----- .../performance_tests/scattergl_test.js | 88 ----- test/jasmine/performance_tests/violin_test.js | 92 ----- 13 files changed, 320 insertions(+), 925 deletions(-) create mode 100644 test/jasmine/performance_tests/all_test.js delete mode 100644 test/jasmine/performance_tests/bar_test.js delete mode 100644 test/jasmine/performance_tests/box_test.js delete mode 100644 test/jasmine/performance_tests/contour_test.js delete mode 100644 test/jasmine/performance_tests/heatmap_test.js delete mode 100644 test/jasmine/performance_tests/histogram_test.js delete mode 100644 test/jasmine/performance_tests/image_test.js delete mode 100644 test/jasmine/performance_tests/scatter_test.js delete mode 100644 test/jasmine/performance_tests/scattergeo_test.js delete mode 100644 test/jasmine/performance_tests/scattergl_test.js delete mode 100644 test/jasmine/performance_tests/violin_test.js diff --git a/.circleci/config.yml b/.circleci/config.yml index c1362c052e4..d79afdb0d98 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -53,11 +53,6 @@ jobs: - run: name: Run performance tests command: .circleci/test.sh performance-jasmine - - run: - name: Combine CSV files - command: | - head -n 1 `ls ~/Downloads/*.csv | head -n 1` > ~/Downloads/all.csv - tail -n+2 -q ~/Downloads/*.csv >> ~/Downloads/all.csv - run: name: Display system information command: npm run system-info > ~/Downloads/system_info.txt diff --git a/test/jasmine/performance_tests/all_test.js b/test/jasmine/performance_tests/all_test.js new file mode 100644 index 00000000000..e3b75642886 --- /dev/null +++ b/test/jasmine/performance_tests/all_test.js @@ -0,0 +1,317 @@ +var createGraphDiv = require('../assets/create_graph_div'); +var delay = require('../assets/delay'); +var d3SelectAll = require('../../strict-d3').selectAll; +var Plotly = require('../../../lib/index'); +var downloadCSV = require('./assets/post_process').downloadCSV; +var nSamples = require('./assets/constants').nSamples; + +var gd = createGraphDiv(); + +const samples = Array.from({ length: nSamples }, (_, i) => i); +const nTimes = samples.length - 1; + +var tests = []; + +for(let traceType of ['image', 'heatmap', 'contour']) { + for(let m of [10, 20, 40, 80, 160, 320, 640]) { + let nx = 5 * m; + let ny = 2 * m; + tests.push({ + nx: nx, + ny: ny, + n: nx * ny, + nTraces: 1, + traceType: traceType, + selector: traceType === 'image' ? 'g.imagelayer.mlayer' : + 'g.' + traceType + 'layer' + }); + } +} + +for(let traceType of ['box', 'violin']) { + for(let mode of ['no points', 'all points']) { + for(let nTraces of [1, 10, 100]) { + for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { + tests.push({ + n:n, + nTraces: nTraces, + traceType: traceType, + mode: mode, + selector: ( + traceType === 'box' ? 'g.trace.boxes' : + traceType === 'violin' ? 'g.trace.violins' : + undefined + ) + }); + } + } + } +} + +for(let traceType of ['scatter', 'scattergl', 'scattergeo']) { + for(let mode of ['markers', 'lines', 'markers+lines']) { + for(let nTraces of [1, 10, 100]) { + for(let n of [1000, 2000, 4000, 8000, 16000, 32000, 64000]) { + tests.push({ + n:n, + nTraces: nTraces, + traceType: traceType, + mode: mode, + selector: ( + traceType === 'scatter' ? 'g.trace.scatter' : + undefined + ) + }); + } + } + } +} + +for(let traceType of ['bar', 'histogram']) { + for(let mode of ['group', 'stack', 'overlay']) { + for(let nTraces of [1, 10, 100]) { + for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { + tests.push({ + n:n, + nTraces: nTraces, + traceType: traceType, + mode: mode, + selector: 'g.trace.bars' + }); + } + } + } +} + +function generateMock(spec) { + var type = spec.traceType; + return ( + (type === 'image') ? makeImage(spec) : + (type === 'heatmap' || type === 'contour') ? makeHeatmap(spec) : + (type === 'box' || type === 'violin') ? makeBox(spec) : + (type === 'bar' || type === 'histogram') ? makeBar(spec) : + (type === 'scatter' || type === 'scattergl') ? makeScatter(spec) : + (type === 'scattergeo') ? makeScatterGeo(spec) : + {} + ); +} + + +function makeImage(spec) { + var A = spec.nx; + var B = spec.ny; + + var x = Array.from({ length: A }, (_, i) => i); + var y = Array.from({ length: B }, (_, i) => i); + var z = []; + for(var k = 0; k < B ; k++) { + z[k] = []; + for(var i = 0; i < A ; i++) { + z[k][i] = [ + Math.floor(127 * (1 + Math.cos(Math.sqrt(i)))), + 0, + Math.floor(127 * (1 + Math.cos(Math.sqrt(k)))), + ]; + } + } + + return { + data: [{ + type: 'image', + x: x, + y: y, + z: z + }], + layout: { + width: 900, + height: 400 + } + }; +} + +function makeHeatmap(spec) { + var A = spec.nx; + var B = spec.ny; + + var x = Array.from({ length: A }, (_, i) => i); + var y = Array.from({ length: B }, (_, i) => i); + var z = []; + for(var k = 0; k < B ; k++) { + z[k] = Array.from({ length: A }, (_, i) => k * Math.cos(Math.sqrt(i))); + } + + return { + data: [{ + type: spec.traceType, + x: x, + y: y, + z: z + }], + layout: { + width: 900, + height: 400 + } + }; +} + +function makeBox(spec) { + var y = Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + var data = []; + var nPerTrace = Math.floor(spec.n / spec.nTraces); + for(var k = 0; k < spec.nTraces; k++) { + var trace = { + type: spec.traceType, + boxpoints: spec.mode === 'all points' ? 'all' : false, + y: y.slice(k * nPerTrace, (k + 1) * nPerTrace), + x: Array.from({ length: nPerTrace }, (_, i) => k) + }; + + if(spec.traceType === 'box') { + trace.boxpoints = spec.mode === 'all points' ? 'all' : false; + } + + if(spec.traceType === 'violin') { + trace.points = spec.mode === 'all points' ? 'all' : false; + } + + data.push(trace); + } + + return { + data: data, + layout: { + showlegend: false, + width: 900, + height: 400 + } + }; +} + +function makeBar(spec) { + var z = Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + var data = []; + var nPerTrace = Math.floor(spec.n / spec.nTraces); + for(var k = 0; k < spec.nTraces; k++) { + if(spec.traceType === 'bar') { + data.push({ + type: 'bar', + y: z.slice(k * nPerTrace, (k + 1) * nPerTrace), + x: Array.from({ length: nPerTrace }, (_, i) => i) + }); + } else if(spec.traceType === 'histogram') { + data.push({ + type: 'histogram', + x: z.slice(k * nPerTrace, (k + 1) * nPerTrace), + y: Array.from({ length: nPerTrace }, (_, i) => i) + }); + } + } + + return { + data: data, + layout: { + barmode: spec.mode, + showlegend: false, + width: 900, + height: 400 + } + }; +} + +function makeScatter(spec) { + var y = Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); + var data = []; + var nPerTrace = Math.floor(spec.n / spec.nTraces); + for(var k = 0; k < spec.nTraces; k++) { + data.push({ + type: spec.traceType, + mode: spec.mode, + y: y.slice(k * nPerTrace, (k + 1) * nPerTrace), + x: Array.from({ length: nPerTrace }, (_, i) => i + k * nPerTrace) + }); + } + + return { + data: data, + layout: { + showlegend: false, + width: 900, + height: 400 + } + }; +} + +function makeScatterGeo(spec) { + var y = Array.from({ length: spec.n }, (_, i) => 0.001 * i * Math.cos(Math.sqrt(i))); + + var data = []; + var nPerTrace = Math.floor(spec.n / spec.nTraces); + for(var k = 0; k < spec.nTraces; k++) { + data.push({ + type: 'scattergeo', + mode: spec.mode, + lat: y.slice(k * nPerTrace, (k + 1) * nPerTrace), + lon: Array.from({ length: nPerTrace }, (_, i) => -180 + 0.005 * (i + k * nPerTrace)) + }); + } + + return { + data: data, + layout: { + showlegend: false, + width: 900, + height: 400 + } + }; +} + + +tests.forEach(function(spec, index) { + describe('Performance test ' + spec.nTraces + ' ' + spec.traceType + ' | mode: ' + spec.mode + ' | size:' + spec.n, function() { + 'use strict'; + + var startTime, endTime; + + beforeEach(function(done) { + jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; + + var mock = generateMock(spec); + + startTime = performance.now(); + + // Wait for actual rendering to complete + requestAnimationFrame(function() { + requestAnimationFrame(function() { + endTime = performance.now(); + done(); + }); + }); + + Plotly.newPlot(gd, mock); + }); + + afterEach(function(done) { + delay(100)().then(done); + }); + + samples.forEach(function(t) { + it('turn: ' + t, function() { + var delta = endTime - startTime; + + if(t === 0) { + tests[index].raw = []; + } + tests[index].raw[t] = delta; + + if(spec.selector) { + var nodes = d3SelectAll(spec.selector); + expect(nodes.size()).toEqual(spec.nTraces); + } + + if(t === nTimes && index === tests.length - 1) { + downloadCSV(tests); + } + }); + }); + }); +}); diff --git a/test/jasmine/performance_tests/assets/post_process.js b/test/jasmine/performance_tests/assets/post_process.js index 5172d0eb1db..b2780d2bbda 100644 --- a/test/jasmine/performance_tests/assets/post_process.js +++ b/test/jasmine/performance_tests/assets/post_process.js @@ -1,4 +1,4 @@ -exports.downloadCSV = function(traceName, allTests) { +exports.downloadCSV = function(allTests) { var str = [ 'number of traces', 'chart type', @@ -12,7 +12,7 @@ exports.downloadCSV = function(traceName, allTests) { for(var i = 0; i < test.raw.length; i++) { str += [ (test.nTraces || 1), - (traceName + (test.mode ? ' ' + test.mode : '')), + (test.traceType + (test.mode ? ' ' + test.mode : '')), test.n, i, test.raw[i] @@ -25,7 +25,7 @@ exports.downloadCSV = function(traceName, allTests) { var myBlob = new Blob([str], {type: 'text/plain'}) var url = window.URL.createObjectURL(myBlob); a.href = url; - a.download = traceName + '.csv'; + a.download = 'all.csv'; a.style.display = 'none'; document.body.append(a); a.click(); diff --git a/test/jasmine/performance_tests/bar_test.js b/test/jasmine/performance_tests/bar_test.js deleted file mode 100644 index 9bb3cbe911e..00000000000 --- a/test/jasmine/performance_tests/bar_test.js +++ /dev/null @@ -1,92 +0,0 @@ -var createGraphDiv = require('../assets/create_graph_div'); -var delay = require('../assets/delay'); -var d3SelectAll = require('../../strict-d3').selectAll; -var Plotly = require('../../../lib/core'); -var PlotlyBar = require('../../../lib/bar'); -var downloadCSV = require('./assets/post_process').downloadCSV; -var nSamples = require('./assets/constants').nSamples; - -Plotly.register(PlotlyBar); - -var gd = createGraphDiv(); - -const samples = Array.from({ length: nSamples }, (_, i) => i); -const nTimes = samples.length - 1; - -var tests = []; -for(let mode of ['group', 'stack']) { - for(let nTraces of [1, 10, 100]) { - for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { - tests.push({ - n:n, - mode: mode, - nTraces: nTraces - }); - } - } -} - -tests.forEach(function(spec, index) { - describe('Performance test ' + spec.nTraces + ' bar | size:' + spec.n + ' | mode: ' + spec.mode, function() { - 'use strict'; - - var startTime, endTime; - - beforeEach(function(done) { - var y = Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); - var data = []; - var nPerTrace = Math.floor(spec.n / spec.nTraces); - for(var k = 0; k < spec.nTraces; k++) { - data.push({ - type: 'bar', - y: y.slice(k * nPerTrace, (k + 1) * nPerTrace), - x: Array.from({ length: nPerTrace }, (_, i) => i) - }); - } - - var mock = { - data: data, - layout: { - barmode: spec.mode, - showlegend: false, - width: 900, - height: 400 - } - }; - - startTime = performance.now(); - - // Wait for actual rendering to complete - requestAnimationFrame(function() { - requestAnimationFrame(function() { - endTime = performance.now(); - done(); - }); - }); - - Plotly.newPlot(gd, mock); - }); - - afterEach(function(done) { - delay(100)().then(done); - }); - - samples.forEach(function(t) { - it('should graph bar traces | turn: ' + t, function() { - var delta = endTime - startTime; - - if(t === 0) { - tests[index].raw = []; - } - tests[index].raw[t] = delta; - - var nodes = d3SelectAll('g.trace.bars'); - expect(nodes.size()).toEqual(spec.nTraces); - - if(t === nTimes && index === tests.length - 1) { - downloadCSV('bar', tests); - } - }); - }); - }); -}); diff --git a/test/jasmine/performance_tests/box_test.js b/test/jasmine/performance_tests/box_test.js deleted file mode 100644 index f9361df1524..00000000000 --- a/test/jasmine/performance_tests/box_test.js +++ /dev/null @@ -1,92 +0,0 @@ -var createGraphDiv = require('../assets/create_graph_div'); -var delay = require('../assets/delay'); -var d3SelectAll = require('../../strict-d3').selectAll; -var Plotly = require('../../../lib/core'); -var PlotlyBox = require('../../../lib/box'); -var downloadCSV = require('./assets/post_process').downloadCSV; -var nSamples = require('./assets/constants').nSamples; - -Plotly.register(PlotlyBox); - -var gd = createGraphDiv(); - -const samples = Array.from({ length: nSamples }, (_, i) => i); -const nTimes = samples.length - 1; - -var tests = []; -for(let mode of ['no points', 'all points']) { - for(let nTraces of [1, 10, 100]) { - for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { - tests.push({ - n:n, - mode: mode, - nTraces: nTraces - }); - } - } -} - -tests.forEach(function(spec, index) { - describe('Performance test ' + spec.nTraces + ' box | size:' + spec.n + ' | mode: ' + spec.mode, function() { - 'use strict'; - - var startTime, endTime; - - beforeEach(function(done) { - var y = Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); - var data = []; - var nPerTrace = Math.floor(spec.n / spec.nTraces); - for(var k = 0; k < spec.nTraces; k++) { - data.push({ - type: 'box', - boxpoints: spec.mode === 'all points' ? 'all' : false, - y: y.slice(k * nPerTrace, (k + 1) * nPerTrace), - x: Array.from({ length: nPerTrace }, (_, i) => k) - }); - } - - var mock = { - data: data, - layout: { - showlegend: false, - width: 900, - height: 400 - } - }; - - startTime = performance.now(); - - // Wait for actual rendering to complete - requestAnimationFrame(function() { - requestAnimationFrame(function() { - endTime = performance.now(); - done(); - }); - }); - - Plotly.newPlot(gd, mock); - }); - - afterEach(function(done) { - delay(100)().then(done); - }); - - samples.forEach(function(t) { - it('should graph box traces | turn: ' + t, function() { - var delta = endTime - startTime; - - if(t === 0) { - tests[index].raw = []; - } - tests[index].raw[t] = delta; - - var nodes = d3SelectAll('g.trace.boxes'); - expect(nodes.size()).toEqual(spec.nTraces); - - if(t === nTimes && index === tests.length - 1) { - downloadCSV('box', tests); - } - }); - }); - }); -}); diff --git a/test/jasmine/performance_tests/contour_test.js b/test/jasmine/performance_tests/contour_test.js deleted file mode 100644 index 2111fd9bd44..00000000000 --- a/test/jasmine/performance_tests/contour_test.js +++ /dev/null @@ -1,92 +0,0 @@ -var createGraphDiv = require('../assets/create_graph_div'); -var delay = require('../assets/delay'); -var d3SelectAll = require('../../strict-d3').selectAll; -var Plotly = require('../../../lib/core'); -var PlotlyContour = require('../../../lib/contour'); -var downloadCSV = require('./assets/post_process').downloadCSV; -var nSamples = require('./assets/constants').nSamples; - -Plotly.register(PlotlyContour); - -var gd = createGraphDiv(); - -const samples = Array.from({ length: nSamples }, (_, i) => i); -const nTimes = samples.length - 1; - -var tests = []; -for(let m of [10, 20, 40, 80, 160, 320, 640]) { - let nx = 5 * m; - let ny = 2 * m; - tests.push({ - nx: nx, - ny: ny, - n: nx * ny, - }); -} - -tests.forEach(function(spec, index) { - describe('Performance test contour | size:' + spec.nx + 'X' + spec.ny, function() { - 'use strict'; - - var A = spec.nx; - var B = spec.ny; - - var x = Array.from({ length: A }, (_, i) => i); - var y = Array.from({ length: B }, (_, i) => i); - var z = []; - for(var k = 0; k < B ; k++) { - z[k] = Array.from({ length: A }, (_, i) => k * Math.cos(Math.sqrt(i))); - } - - var mock = { - data: [{ - type: 'contour', - x: x, - y: y, - z: z - }], - layout: { - width: 900, - height: 400 - } - }; - - var startTime, endTime; - - beforeEach(function(done) { - startTime = performance.now(); - - // Wait for actual rendering to complete - requestAnimationFrame(function() { - requestAnimationFrame(function() { - endTime = performance.now(); - done(); - }); - }); - - Plotly.newPlot(gd, mock); - }); - - afterEach(function(done) { - delay(100)().then(done); - }); - - samples.forEach(function(t) { - it('should graph contour traces | turn: ' + t, function() { - var delta = endTime - startTime; - - if(t === 0) { - tests[index].raw = []; - } - tests[index].raw[t] = delta; - - var nodes = d3SelectAll('g.contourlayer'); - expect(nodes.size()).toEqual(1); - - if(t === nTimes && index === tests.length - 1) { - downloadCSV('contour', tests); - } - }); - }); - }); -}); diff --git a/test/jasmine/performance_tests/heatmap_test.js b/test/jasmine/performance_tests/heatmap_test.js deleted file mode 100644 index 93d8ac8c16a..00000000000 --- a/test/jasmine/performance_tests/heatmap_test.js +++ /dev/null @@ -1,92 +0,0 @@ -var createGraphDiv = require('../assets/create_graph_div'); -var delay = require('../assets/delay'); -var d3SelectAll = require('../../strict-d3').selectAll; -var Plotly = require('../../../lib/core'); -var PlotlyHeatmap = require('../../../lib/heatmap'); -var downloadCSV = require('./assets/post_process').downloadCSV; -var nSamples = require('./assets/constants').nSamples; - -Plotly.register(PlotlyHeatmap); - -var gd = createGraphDiv(); - -const samples = Array.from({ length: nSamples }, (_, i) => i); -const nTimes = samples.length - 1; - -var tests = []; -for(let m of [10, 20, 40, 80, 160, 320, 640]) { - let nx = 5 * m; - let ny = 2 * m; - tests.push({ - nx: nx, - ny: ny, - n: nx * ny, - }); -} - -tests.forEach(function(spec, index) { - describe('Performance test heatmap | size:' + spec.nx + 'X' + spec.ny, function() { - 'use strict'; - - var A = spec.nx; - var B = spec.ny; - - var x = Array.from({ length: A }, (_, i) => i); - var y = Array.from({ length: B }, (_, i) => i); - var z = []; - for(var k = 0; k < B ; k++) { - z[k] = Array.from({ length: A }, (_, i) => k * Math.cos(Math.sqrt(i))); - } - - var mock = { - data: [{ - type: 'heatmap', - x: x, - y: y, - z: z - }], - layout: { - width: 900, - height: 400 - } - }; - - var startTime, endTime; - - beforeEach(function(done) { - startTime = performance.now(); - - // Wait for actual rendering to complete - requestAnimationFrame(function() { - requestAnimationFrame(function() { - endTime = performance.now(); - done(); - }); - }); - - Plotly.newPlot(gd, mock); - }); - - afterEach(function(done) { - delay(100)().then(done); - }); - - samples.forEach(function(t) { - it('should graph heatmap traces | turn: ' + t, function() { - var delta = endTime - startTime; - - if(t === 0) { - tests[index].raw = []; - } - tests[index].raw[t] = delta; - - var nodes = d3SelectAll('g.heatmaplayer'); - expect(nodes.size()).toEqual(1); - - if(t === nTimes && index === tests.length - 1) { - downloadCSV('heatmap', tests); - } - }); - }); - }); -}); diff --git a/test/jasmine/performance_tests/histogram_test.js b/test/jasmine/performance_tests/histogram_test.js deleted file mode 100644 index 66a03e613f7..00000000000 --- a/test/jasmine/performance_tests/histogram_test.js +++ /dev/null @@ -1,92 +0,0 @@ -var createGraphDiv = require('../assets/create_graph_div'); -var delay = require('../assets/delay'); -var d3SelectAll = require('../../strict-d3').selectAll; -var Plotly = require('../../../lib/core'); -var PlotlyHistogram = require('../../../lib/histogram'); -var downloadCSV = require('./assets/post_process').downloadCSV; -var nSamples = require('./assets/constants').nSamples; - -Plotly.register(PlotlyHistogram); - -var gd = createGraphDiv(); - -const samples = Array.from({ length: nSamples }, (_, i) => i); -const nTimes = samples.length - 1; - -var tests = []; -for(let mode of ['group', 'stack']) { - for(let nTraces of [1, 10, 100]) { - for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { - tests.push({ - n:n, - mode: mode, - nTraces: nTraces - }); - } - } -} - -tests.forEach(function(spec, index) { - describe('Performance test ' + spec.nTraces + ' histogram | size:' + spec.n + ' | mode: ' + spec.mode, function() { - 'use strict'; - - var startTime, endTime; - - beforeEach(function(done) { - var z = Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); - var data = []; - var nPerTrace = Math.floor(spec.n / spec.nTraces); - for(var k = 0; k < spec.nTraces; k++) { - data.push({ - type: 'histogram', - x: z.slice(k * nPerTrace, (k + 1) * nPerTrace), - y: Array.from({ length: nPerTrace }, (_, i) => i) - }); - } - - var mock = { - data: data, - layout: { - barmode: spec.mode, - showlegend: false, - width: 900, - height: 400 - } - }; - - startTime = performance.now(); - - // Wait for actual rendering to complete - requestAnimationFrame(function() { - requestAnimationFrame(function() { - endTime = performance.now(); - done(); - }); - }); - - Plotly.newPlot(gd, mock); - }); - - afterEach(function(done) { - delay(100)().then(done); - }); - - samples.forEach(function(t) { - it('should graph histogram traces | turn: ' + t, function() { - var delta = endTime - startTime; - - if(t === 0) { - tests[index].raw = []; - } - tests[index].raw[t] = delta; - - var nodes = d3SelectAll('g.trace.bars'); - expect(nodes.size()).toEqual(spec.nTraces); - - if(t === nTimes && index === tests.length - 1) { - downloadCSV('histogram', tests); - } - }); - }); - }); -}); diff --git a/test/jasmine/performance_tests/image_test.js b/test/jasmine/performance_tests/image_test.js deleted file mode 100644 index 3e87eec172e..00000000000 --- a/test/jasmine/performance_tests/image_test.js +++ /dev/null @@ -1,99 +0,0 @@ -var createGraphDiv = require('../assets/create_graph_div'); -var delay = require('../assets/delay'); -var d3SelectAll = require('../../strict-d3').selectAll; -var Plotly = require('../../../lib/core'); -var PlotlyImage = require('../../../lib/image'); -var downloadCSV = require('./assets/post_process').downloadCSV; -var nSamples = require('./assets/constants').nSamples; - -Plotly.register(PlotlyImage); - -var gd = createGraphDiv(); - -const samples = Array.from({ length: nSamples }, (_, i) => i); -const nTimes = samples.length - 1; - -var tests = []; -for(let m of [10, 20, 40, 80, 160, 320, 640]) { - let nx = 5 * m; - let ny = 2 * m; - tests.push({ - nx: nx, - ny: ny, - n: nx * ny, - }); -} - -tests.forEach(function(spec, index) { - describe('Performance test image | size:' + spec.nx + 'X' + spec.ny, function() { - 'use strict'; - - var A = spec.nx; - var B = spec.ny; - - var x = Array.from({ length: A }, (_, i) => i); - var y = Array.from({ length: B }, (_, i) => i); - var z = []; - for(var k = 0; k < B ; k++) { - z[k] = []; - for(var i = 0; i < A ; i++) { - z[k][i] = [ - Math.floor(127 * (1 + Math.cos(Math.sqrt(i)))), - 0, - Math.floor(127 * (1 + Math.cos(Math.sqrt(k)))), - ]; - } - } - - var mock = { - data: [{ - type: 'image', - x: x, - y: y, - z: z - }], - layout: { - width: 900, - height: 400 - } - }; - - var startTime, endTime; - - beforeEach(function(done) { - startTime = performance.now(); - - // Wait for actual rendering to complete - requestAnimationFrame(function() { - requestAnimationFrame(function() { - endTime = performance.now(); - done(); - }); - }); - - Plotly.newPlot(gd, mock); - }); - - afterEach(function(done) { - delay(100)().then(done); - }); - - samples.forEach(function(t) { - it('should graph image traces | turn: ' + t, function() { - var delta = endTime - startTime; - - if(t === 0) { - tests[index].raw = []; - } - tests[index].raw[t] = delta; - - var nodes = d3SelectAll('g.imagelayer.mlayer'); - expect(nodes.size()).toEqual(1); - - if(t === nTimes && index === tests.length - 1) { - downloadCSV('image', tests); - } - }); - }); - }); -}); diff --git a/test/jasmine/performance_tests/scatter_test.js b/test/jasmine/performance_tests/scatter_test.js deleted file mode 100644 index 97b21112856..00000000000 --- a/test/jasmine/performance_tests/scatter_test.js +++ /dev/null @@ -1,89 +0,0 @@ -var createGraphDiv = require('../assets/create_graph_div'); -var delay = require('../assets/delay'); -var d3SelectAll = require('../../strict-d3').selectAll; -var Plotly = require('../../../lib/core'); -var downloadCSV = require('./assets/post_process').downloadCSV; -var nSamples = require('./assets/constants').nSamples; - -var gd = createGraphDiv(); - -const samples = Array.from({ length: nSamples }, (_, i) => i); -const nTimes = samples.length - 1; - -var tests = []; -for(let mode of ['markers', 'lines', 'markers+lines']) { - for(let nTraces of [1, 10, 100]) { - for(let n of [1000, 2000, 4000, 8000, 16000, 32000, 64000]) { - tests.push({ - n:n, - mode: mode, - nTraces: nTraces - }); - } - } -} - -tests.forEach(function(spec, index) { - describe('Performance test ' + spec.nTraces + ' scatter | size:' + spec.n + ' | mode: ' + spec.mode, function() { - 'use strict'; - - var startTime, endTime; - - beforeEach(function(done) { - var y = Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); - var data = []; - var nPerTrace = Math.floor(spec.n / spec.nTraces); - for(var k = 0; k < spec.nTraces; k++) { - data.push({ - type: 'scatter', - mode: spec.mode, - y: y.slice(k * nPerTrace, (k + 1) * nPerTrace), - x: Array.from({ length: nPerTrace }, (_, i) => i + k * nPerTrace) - }); - } - - var mock = { - data: data, - layout: { - showlegend: false, - width: 900, - height: 400 - } - }; - - startTime = performance.now(); - - // Wait for actual rendering to complete - requestAnimationFrame(function() { - requestAnimationFrame(function() { - endTime = performance.now(); - done(); - }); - }); - - Plotly.newPlot(gd, mock); - }); - - afterEach(function(done) { - delay(100)().then(done); - }); - - samples.forEach(function(t) { - it('should graph scatter traces | turn: ' + t, function() { - var delta = endTime - startTime; - - if(t === 0) { - tests[index].raw = []; - } - tests[index].raw[t] = delta; - - var nodes = d3SelectAll('g.trace.scatter'); - expect(nodes.size()).toEqual(spec.nTraces); - - if(t === nTimes && index === tests.length - 1) { - downloadCSV('scatter', tests); - } - }); - }); - }); -}); diff --git a/test/jasmine/performance_tests/scattergeo_test.js b/test/jasmine/performance_tests/scattergeo_test.js deleted file mode 100644 index 8c456201408..00000000000 --- a/test/jasmine/performance_tests/scattergeo_test.js +++ /dev/null @@ -1,89 +0,0 @@ -var createGraphDiv = require('../assets/create_graph_div'); -var delay = require('../assets/delay'); -var Plotly = require('../../../lib/core'); -var PlotlyScattergeo = require('../../../lib/scattergeo'); -var downloadCSV = require('./assets/post_process').downloadCSV; -var nSamples = require('./assets/constants').nSamples; - -Plotly.register(PlotlyScattergeo); - -var gd = createGraphDiv(); - -const samples = Array.from({ length: nSamples }, (_, i) => i); -const nTimes = samples.length - 1; - -var tests = []; -for(let mode of ['markers', 'lines', 'markers+lines']) { - for(let nTraces of [1, 10, 100]) { - for(let n of [1000, 2000, 4000, 8000, 16000, 32000, 64000]) { - tests.push({ - n:n, - mode: mode, - nTraces: nTraces - }); - } - } -} - -tests.forEach(function(spec, index) { - describe('Performance test ' + spec.nTraces + ' scattergeo | size:' + spec.n + ' | mode: ' + spec.mode, function() { - 'use strict'; - - var startTime, endTime; - - beforeEach(function(done) { - var y = Array.from({ length: spec.n }, (_, i) => 0.001 * i * Math.cos(Math.sqrt(i))); - - var data = []; - var nPerTrace = Math.floor(spec.n / spec.nTraces); - for(var k = 0; k < spec.nTraces; k++) { - data.push({ - type: 'scattergeo', - mode: spec.mode, - lat: y.slice(k * nPerTrace, (k + 1) * nPerTrace), - lon: Array.from({ length: nPerTrace }, (_, i) => -180 + 0.005 * (i + k * nPerTrace)) - }); - } - - var mock = { - data: data, - layout: { - showlegend: false, - width: 900, - height: 400 - } - }; - - startTime = performance.now(); - - // Wait for actual rendering to complete - requestAnimationFrame(function() { - requestAnimationFrame(function() { - endTime = performance.now(); - done(); - }); - }); - - Plotly.newPlot(gd, mock); - }); - - afterEach(function(done) { - delay(100)().then(done); - }); - - samples.forEach(function(t) { - it('should graph scattergeo traces | turn: ' + t, function() { - var delta = endTime - startTime; - - if(t === 0) { - tests[index].raw = []; - } - tests[index].raw[t] = delta; - - if(t === nTimes && index === tests.length - 1) { - downloadCSV('scattergeo', tests); - } - }); - }); - }); -}); diff --git a/test/jasmine/performance_tests/scattergl_test.js b/test/jasmine/performance_tests/scattergl_test.js deleted file mode 100644 index 05261f4e981..00000000000 --- a/test/jasmine/performance_tests/scattergl_test.js +++ /dev/null @@ -1,88 +0,0 @@ -var createGraphDiv = require('../assets/create_graph_div'); -var delay = require('../assets/delay'); -var Plotly = require('../../../lib/core'); -var PlotlyScattergl = require('../../../lib/scattergl'); -var downloadCSV = require('./assets/post_process').downloadCSV; -var nSamples = require('./assets/constants').nSamples; - -Plotly.register(PlotlyScattergl); - -var gd = createGraphDiv(); - -const samples = Array.from({ length: nSamples }, (_, i) => i); -const nTimes = samples.length - 1; - -var tests = []; -for(let mode of ['markers', 'lines', 'markers+lines']) { - for(let nTraces of [1, 10, 100]) { - for(let n of [1000, 2000, 4000, 8000, 16000, 32000, 64000]) { - tests.push({ - n:n, - mode: mode, - nTraces: nTraces - }); - } - } -} - -tests.forEach(function(spec, index) { - describe('Performance test ' + spec.nTraces + ' scattergl | size:' + spec.n + ' | mode: ' + spec.mode, function() { - 'use strict'; - - var startTime, endTime; - - beforeEach(function(done) { - var y = Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); - var data = []; - var nPerTrace = Math.floor(spec.n / spec.nTraces); - for(var k = 0; k < spec.nTraces; k++) { - data.push({ - type: 'scattergl', - mode: spec.mode, - y: y.slice(k * nPerTrace, (k + 1) * nPerTrace), - x: Array.from({ length: nPerTrace }, (_, i) => i + k * nPerTrace) - }); - } - - var mock = { - data: data, - layout: { - showlegend: false, - width: 900, - height: 400 - } - }; - - startTime = performance.now(); - - // Wait for actual rendering to complete - requestAnimationFrame(function() { - requestAnimationFrame(function() { - endTime = performance.now(); - done(); - }); - }); - - Plotly.newPlot(gd, mock); - }); - - afterEach(function(done) { - delay(100)().then(done); - }); - - samples.forEach(function(t) { - it('should graph scattergl traces | turn: ' + t, function() { - var delta = endTime - startTime; - - if(t === 0) { - tests[index].raw = []; - } - tests[index].raw[t] = delta; - - if(t === nTimes && index === tests.length - 1) { - downloadCSV('scattergl', tests); - } - }); - }); - }); -}); diff --git a/test/jasmine/performance_tests/violin_test.js b/test/jasmine/performance_tests/violin_test.js deleted file mode 100644 index 2688490d2ac..00000000000 --- a/test/jasmine/performance_tests/violin_test.js +++ /dev/null @@ -1,92 +0,0 @@ -var createGraphDiv = require('../assets/create_graph_div'); -var delay = require('../assets/delay'); -var d3SelectAll = require('../../strict-d3').selectAll; -var Plotly = require('../../../lib/core'); -var PlotlyViolin = require('../../../lib/violin'); -var downloadCSV = require('./assets/post_process').downloadCSV; -var nSamples = require('./assets/constants').nSamples; - -Plotly.register(PlotlyViolin); - -var gd = createGraphDiv(); - -const samples = Array.from({ length: nSamples }, (_, i) => i); -const nTimes = samples.length - 1; - -var tests = []; -for(let mode of['no points', 'all points']) { - for(let nTraces of [1, 10, 100]) { - for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { - tests.push({ - n:n, - mode: mode, - nTraces: nTraces - }); - } - } -} - -tests.forEach(function(spec, index) { - describe('Performance test ' + spec.nTraces + ' violin | size:' + spec.n + ' | mode: ' + spec.mode, function() { - 'use strict'; - - var startTime, endTime; - - beforeEach(function(done) { - var y = Array.from({ length: spec.n }, (_, i) => i * Math.cos(Math.sqrt(i))); - var data = []; - var nPerTrace = Math.floor(spec.n / spec.nTraces); - for(var k = 0; k < spec.nTraces; k++) { - data.push({ - type: 'violin', - points: spec.mode === 'all points' ? 'all' : false, - y: y.slice(k * nPerTrace, (k + 1) * nPerTrace), - x: Array.from({ length: nPerTrace }, (_, i) => k) - }); - } - - var mock = { - data: data, - layout: { - showlegend: false, - width: 900, - height: 400 - } - }; - - startTime = performance.now(); - - // Wait for actual rendering to complete - requestAnimationFrame(function() { - requestAnimationFrame(function() { - endTime = performance.now(); - done(); - }); - }); - - Plotly.newPlot(gd, mock); - }); - - afterEach(function(done) { - delay(100)().then(done); - }); - - samples.forEach(function(t) { - it('should graph violin traces | turn: ' + t, function() { - var delta = endTime - startTime; - - if(t === 0) { - tests[index].raw = []; - } - tests[index].raw[t] = delta; - - var nodes = d3SelectAll('g.trace.violins'); - expect(nodes.size()).toEqual(spec.nTraces); - - if(t === nTimes && index === tests.length - 1) { - downloadCSV('violin', tests); - } - }); - }); - }); -}); From bcb165decbb10026735fffe982f18a4efea00d83 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 24 Jun 2025 08:02:16 -0400 Subject: [PATCH 30/46] improve tests --- test/jasmine/performance_tests/all_test.js | 33 ++++++++-------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/test/jasmine/performance_tests/all_test.js b/test/jasmine/performance_tests/all_test.js index e3b75642886..54e61928e14 100644 --- a/test/jasmine/performance_tests/all_test.js +++ b/test/jasmine/performance_tests/all_test.js @@ -267,35 +267,26 @@ function makeScatterGeo(spec) { tests.forEach(function(spec, index) { - describe('Performance test ' + spec.nTraces + ' ' + spec.traceType + ' | mode: ' + spec.mode + ' | size:' + spec.n, function() { + describe('Performance test ' + spec.nTraces + ' ' + spec.traceType + (spec.mode ? ' | mode: ' + spec.mode : '') + ' | size:' + spec.n, function() { 'use strict'; - var startTime, endTime; - - beforeEach(function(done) { - jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; - - var mock = generateMock(spec); - - startTime = performance.now(); + samples.forEach(function(t) { + it('turn: ' + t, function() { + var startTime, endTime; - // Wait for actual rendering to complete - requestAnimationFrame(function() { requestAnimationFrame(function() { - endTime = performance.now(); - done(); + // Wait for actual rendering instead of promise + requestAnimationFrame(function() { + endTime = performance.now(); + }); }); - }); - Plotly.newPlot(gd, mock); - }); + var mock = generateMock(spec); - afterEach(function(done) { - delay(100)().then(done); - }); + startTime = performance.now(); + + Plotly.newPlot(gd, mock); - samples.forEach(function(t) { - it('turn: ' + t, function() { var delta = endTime - startTime; if(t === 0) { From b9611ae090bc09260b08d2f2fa7a0f20dbe84c5e Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 24 Jun 2025 09:43:09 -0400 Subject: [PATCH 31/46] fix time calculation --- test/jasmine/performance_tests/all_test.js | 37 ++++++++++++---------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/test/jasmine/performance_tests/all_test.js b/test/jasmine/performance_tests/all_test.js index 54e61928e14..8693964209f 100644 --- a/test/jasmine/performance_tests/all_test.js +++ b/test/jasmine/performance_tests/all_test.js @@ -271,13 +271,32 @@ tests.forEach(function(spec, index) { 'use strict'; samples.forEach(function(t) { - it('turn: ' + t, function() { + it('turn: ' + t, function(done) { var startTime, endTime; requestAnimationFrame(function() { // Wait for actual rendering instead of promise requestAnimationFrame(function() { endTime = performance.now(); + + var delta = endTime - startTime; + console.log(delta) + + if(t === 0) { + tests[index].raw = []; + } + tests[index].raw[t] = delta; + + if(spec.selector) { + var nodes = d3SelectAll(spec.selector); + expect(nodes.size()).toEqual(spec.nTraces); + } + + if(t === nTimes && index === tests.length - 1) { + downloadCSV(tests); + } + + done(); }); }); @@ -286,22 +305,6 @@ tests.forEach(function(spec, index) { startTime = performance.now(); Plotly.newPlot(gd, mock); - - var delta = endTime - startTime; - - if(t === 0) { - tests[index].raw = []; - } - tests[index].raw[t] = delta; - - if(spec.selector) { - var nodes = d3SelectAll(spec.selector); - expect(nodes.size()).toEqual(spec.nTraces); - } - - if(t === nTimes && index === tests.length - 1) { - downloadCSV(tests); - } }); }); }); From f6aa0aba6b708c2f0ab298d662eb8c6ec9736aee Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 24 Jun 2025 09:44:57 -0400 Subject: [PATCH 32/46] remove console.log --- test/jasmine/performance_tests/all_test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/jasmine/performance_tests/all_test.js b/test/jasmine/performance_tests/all_test.js index 8693964209f..2b6dcdd62c7 100644 --- a/test/jasmine/performance_tests/all_test.js +++ b/test/jasmine/performance_tests/all_test.js @@ -280,7 +280,6 @@ tests.forEach(function(spec, index) { endTime = performance.now(); var delta = endTime - startTime; - console.log(delta) if(t === 0) { tests[index].raw = []; From 80ac7ae30e71aa2605d31e41d8fe38cd331bfd9f Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 24 Jun 2025 09:57:44 -0400 Subject: [PATCH 33/46] add delay between tests --- test/jasmine/performance_tests/all_test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/jasmine/performance_tests/all_test.js b/test/jasmine/performance_tests/all_test.js index 2b6dcdd62c7..bb6e6408355 100644 --- a/test/jasmine/performance_tests/all_test.js +++ b/test/jasmine/performance_tests/all_test.js @@ -270,6 +270,10 @@ tests.forEach(function(spec, index) { describe('Performance test ' + spec.nTraces + ' ' + spec.traceType + (spec.mode ? ' | mode: ' + spec.mode : '') + ' | size:' + spec.n, function() { 'use strict'; + afterEach(function(done) { + delay(100)().then(done); + }); + samples.forEach(function(t) { it('turn: ' + t, function(done) { var startTime, endTime; From fad4b36ef35f4652e256c191a4098b472c63c3ea Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 24 Jun 2025 11:55:50 -0400 Subject: [PATCH 34/46] improve collecting csv if the last one fails --- test/jasmine/performance_tests/all_test.js | 21 ++++++++----------- .../performance_tests/assets/post_process.js | 7 +++++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/test/jasmine/performance_tests/all_test.js b/test/jasmine/performance_tests/all_test.js index bb6e6408355..88f9fdcc5cc 100644 --- a/test/jasmine/performance_tests/all_test.js +++ b/test/jasmine/performance_tests/all_test.js @@ -8,7 +8,6 @@ var nSamples = require('./assets/constants').nSamples; var gd = createGraphDiv(); const samples = Array.from({ length: nSamples }, (_, i) => i); -const nTimes = samples.length - 1; var tests = []; @@ -51,7 +50,7 @@ for(let traceType of ['box', 'violin']) { for(let traceType of ['scatter', 'scattergl', 'scattergeo']) { for(let mode of ['markers', 'lines', 'markers+lines']) { for(let nTraces of [1, 10, 100]) { - for(let n of [1000, 2000, 4000, 8000, 16000, 32000, 64000]) { + for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { tests.push({ n:n, nTraces: nTraces, @@ -266,14 +265,16 @@ function makeScatterGeo(spec) { } -tests.forEach(function(spec, index) { - describe('Performance test ' + spec.nTraces + ' ' + spec.traceType + (spec.mode ? ' | mode: ' + spec.mode : '') + ' | size:' + spec.n, function() { - 'use strict'; +describe('Performance test various traces', function() { + 'use strict'; - afterEach(function(done) { - delay(100)().then(done); - }); + afterAll(function(done) { + downloadCSV(tests); + // delay for the download to be completed + delay(1000)().then(done) + }); + tests.forEach(function(spec, index) { samples.forEach(function(t) { it('turn: ' + t, function(done) { var startTime, endTime; @@ -295,10 +296,6 @@ tests.forEach(function(spec, index) { expect(nodes.size()).toEqual(spec.nTraces); } - if(t === nTimes && index === tests.length - 1) { - downloadCSV(tests); - } - done(); }); }); diff --git a/test/jasmine/performance_tests/assets/post_process.js b/test/jasmine/performance_tests/assets/post_process.js index b2780d2bbda..225b67d1e08 100644 --- a/test/jasmine/performance_tests/assets/post_process.js +++ b/test/jasmine/performance_tests/assets/post_process.js @@ -6,16 +6,19 @@ exports.downloadCSV = function(allTests) { 'run id', 'rendering time(ms)' ].join(',') + '\n'; + for(var k = 0; k < allTests.length; k++) { var test = allTests[k]; - for(var i = 0; i < test.raw.length; i++) { + var raw = test.raw || []; + + for(var i = 0; i < raw.length; i++) { str += [ (test.nTraces || 1), (test.traceType + (test.mode ? ' ' + test.mode : '')), test.n, i, - test.raw[i] + raw[i] ].join(',') + '\n'; } } From cd874ddf1065ad1db9a45752e77eac6b46bef2c3 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Thu, 26 Jun 2025 11:18:21 -0400 Subject: [PATCH 35/46] fail rendering after 4 seconds --- test/jasmine/performance_tests/all_test.js | 30 +++++++++++++++++----- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/test/jasmine/performance_tests/all_test.js b/test/jasmine/performance_tests/all_test.js index 88f9fdcc5cc..2c3b4d1f3e6 100644 --- a/test/jasmine/performance_tests/all_test.js +++ b/test/jasmine/performance_tests/all_test.js @@ -4,6 +4,7 @@ var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/index'); var downloadCSV = require('./assets/post_process').downloadCSV; var nSamples = require('./assets/constants').nSamples; +var MAX_RENDERING_TIME = 4000; var gd = createGraphDiv(); @@ -277,31 +278,48 @@ describe('Performance test various traces', function() { tests.forEach(function(spec, index) { samples.forEach(function(t) { it('turn: ' + t, function(done) { - var startTime, endTime; + if(t === 0) { + tests[index].raw = []; + } - requestAnimationFrame(function() { + var timerID; + var requestID1, requestID2; + + var startTime, endTime; + + requestID1 = requestAnimationFrame(function() { // Wait for actual rendering instead of promise - requestAnimationFrame(function() { + requestID2 = requestAnimationFrame(function() { endTime = performance.now(); var delta = endTime - startTime; - if(t === 0) { - tests[index].raw = []; + if(tests[index].raw[t] === undefined) { + tests[index].raw[t] = delta; } - tests[index].raw[t] = delta; if(spec.selector) { var nodes = d3SelectAll(spec.selector); expect(nodes.size()).toEqual(spec.nTraces); } + clearTimeout(timerID); + done(); }); }); var mock = generateMock(spec); + timerID = setTimeout(() => { + tests[index].raw[t] = 'none'; + + cancelAnimationFrame(requestID2); + cancelAnimationFrame(requestID1); + + done.fail('Takes too much time'); + }, MAX_RENDERING_TIME); + startTime = performance.now(); Plotly.newPlot(gd, mock); From 3fd0dfc18bdb8371ec8643d7e37abefdc5fbf3c7 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Thu, 26 Jun 2025 11:50:43 -0400 Subject: [PATCH 36/46] add test descriptions --- test/jasmine/performance_tests/all_test.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/test/jasmine/performance_tests/all_test.js b/test/jasmine/performance_tests/all_test.js index 2c3b4d1f3e6..e5aa61ec614 100644 --- a/test/jasmine/performance_tests/all_test.js +++ b/test/jasmine/performance_tests/all_test.js @@ -4,7 +4,7 @@ var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/index'); var downloadCSV = require('./assets/post_process').downloadCSV; var nSamples = require('./assets/constants').nSamples; -var MAX_RENDERING_TIME = 4000; +var MAX_RENDERING_TIME = 4000; var gd = createGraphDiv(); @@ -275,9 +275,17 @@ describe('Performance test various traces', function() { delay(1000)().then(done) }); + afterEach(function(done) { + // delay to avoid unexpected crash on CircleCI + delay(100)().then(done) + }); + tests.forEach(function(spec, index) { samples.forEach(function(t) { - it('turn: ' + t, function(done) { + it( + spec.nTraces + ' ' + spec.traceType + + (spec.mode ? ' | mode: ' + spec.mode : '') + + ' | size:' + spec.n + ' | turn: ' + t, function(done) { if(t === 0) { tests[index].raw = []; } @@ -285,7 +293,7 @@ describe('Performance test various traces', function() { var timerID; var requestID1, requestID2; - var startTime, endTime; + var startTime, endTime; requestID1 = requestAnimationFrame(function() { // Wait for actual rendering instead of promise @@ -312,12 +320,14 @@ describe('Performance test various traces', function() { var mock = generateMock(spec); timerID = setTimeout(() => { + endTime = performance.now(); + tests[index].raw[t] = 'none'; cancelAnimationFrame(requestID2); cancelAnimationFrame(requestID1); - done.fail('Takes too much time'); + done.fail('Takes too much time: ' + (endTime - startTime)); }, MAX_RENDERING_TIME); startTime = performance.now(); From d2baf677d7a121baf29062459516f333aa410e9e Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Thu, 26 Jun 2025 12:25:43 -0400 Subject: [PATCH 37/46] delay was not helpful for passing on CI --- test/jasmine/performance_tests/all_test.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/jasmine/performance_tests/all_test.js b/test/jasmine/performance_tests/all_test.js index e5aa61ec614..73ef0480fb2 100644 --- a/test/jasmine/performance_tests/all_test.js +++ b/test/jasmine/performance_tests/all_test.js @@ -275,11 +275,6 @@ describe('Performance test various traces', function() { delay(1000)().then(done) }); - afterEach(function(done) { - // delay to avoid unexpected crash on CircleCI - delay(100)().then(done) - }); - tests.forEach(function(spec, index) { samples.forEach(function(t) { it( From 577f7ace5467fbaa23c3078e08b10941650dbf13 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Thu, 26 Jun 2025 16:53:56 -0400 Subject: [PATCH 38/46] pass arguments to isolate performance tests --- tasks/test_performance.js | 6 +- test/jasmine/karma.conf.js | 14 +++- test/jasmine/performance_tests/all_test.js | 93 ++++++++++++---------- 3 files changed, 70 insertions(+), 43 deletions(-) diff --git a/tasks/test_performance.js b/tasks/test_performance.js index 1d1c9487536..26b2cc83a1f 100644 --- a/tasks/test_performance.js +++ b/tasks/test_performance.js @@ -20,7 +20,11 @@ glob(pathToJasminePerformanceTests + '/*.js').then(function(files) { 'karma', 'start', path.join(constants.pathToRoot, 'test', 'jasmine', 'karma.conf.js'), '--performanceTest=' + path.basename(file), - '--nowatch' + '--nowatch', + '--tracesType=scattergl', + '--tracesMode=markers', + '--tracesCount=1', + '--tracesPoints=1000', ].join(' '); console.log('Running: ' + cmd); diff --git a/test/jasmine/karma.conf.js b/test/jasmine/karma.conf.js index 4653e346f44..7f24674cd7a 100644 --- a/test/jasmine/karma.conf.js +++ b/test/jasmine/karma.conf.js @@ -156,7 +156,7 @@ var hasSpecReporter = reporters.indexOf('spec') !== -1; if(!hasSpecReporter && argv.showSkipped) reporters.push('spec'); if(argv.verbose) reporters.push('verbose'); -function func(config) { +var func = function(config) { // level of logging // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // @@ -172,8 +172,18 @@ function func(config) { level: 'debug' }; + if(isPerformanceTest) { + func.defaultConfig.client = func.defaultConfig.client || {}; + func.defaultConfig.client.testCase = { + tracesType: config.tracesType, + tracesMode: config.tracesMode, + tracesCount: config.tracesCount, + tracesPoints: config.tracesPoints, + }; + } + config.set(func.defaultConfig); -} +}; func.defaultConfig = { diff --git a/test/jasmine/performance_tests/all_test.js b/test/jasmine/performance_tests/all_test.js index 73ef0480fb2..46b73d348e2 100644 --- a/test/jasmine/performance_tests/all_test.js +++ b/test/jasmine/performance_tests/all_test.js @@ -276,59 +276,72 @@ describe('Performance test various traces', function() { }); tests.forEach(function(spec, index) { - samples.forEach(function(t) { - it( - spec.nTraces + ' ' + spec.traceType + - (spec.mode ? ' | mode: ' + spec.mode : '') + - ' | size:' + spec.n + ' | turn: ' + t, function(done) { - if(t === 0) { - tests[index].raw = []; - } - - var timerID; - var requestID1, requestID2; - - var startTime, endTime; - - requestID1 = requestAnimationFrame(function() { - // Wait for actual rendering instead of promise - requestID2 = requestAnimationFrame(function() { - endTime = performance.now(); + var testIt = true; + + var testCase = __karma__.config.testCase; + + if(testCase) { + if(testCase.tracesType && testCase.tracesType !== spec.traceType) testIt = false; + if(testCase.tracesCount && testCase.tracesCount !== spec.nTraces) testIt = false; + if(testCase.tracesMode && testCase.tracesMode !== spec.mode) testIt = false; + if(testCase.tracesPoints && testCase.tracesPoints !== spec.n) testIt = false; + } + + if(testIt) { + samples.forEach(function(t) { + it( + spec.nTraces + ' ' + spec.traceType + + (spec.mode ? ' | mode: ' + spec.mode : '') + + ' | size:' + spec.n + ' | turn: ' + t, function(done) { + if(t === 0) { + tests[index].raw = []; + } + + var timerID; + var requestID1, requestID2; + + var startTime, endTime; - var delta = endTime - startTime; + requestID1 = requestAnimationFrame(function() { + // Wait for actual rendering instead of promise + requestID2 = requestAnimationFrame(function() { + endTime = performance.now(); - if(tests[index].raw[t] === undefined) { - tests[index].raw[t] = delta; - } + var delta = endTime - startTime; - if(spec.selector) { - var nodes = d3SelectAll(spec.selector); - expect(nodes.size()).toEqual(spec.nTraces); - } + if(tests[index].raw[t] === undefined) { + tests[index].raw[t] = delta; + } - clearTimeout(timerID); + if(spec.selector) { + var nodes = d3SelectAll(spec.selector); + expect(nodes.size()).toEqual(spec.nTraces); + } - done(); + clearTimeout(timerID); + + done(); + }); }); - }); - var mock = generateMock(spec); + var mock = generateMock(spec); - timerID = setTimeout(() => { - endTime = performance.now(); + timerID = setTimeout(() => { + endTime = performance.now(); - tests[index].raw[t] = 'none'; + tests[index].raw[t] = 'none'; - cancelAnimationFrame(requestID2); - cancelAnimationFrame(requestID1); + cancelAnimationFrame(requestID2); + cancelAnimationFrame(requestID1); - done.fail('Takes too much time: ' + (endTime - startTime)); - }, MAX_RENDERING_TIME); + done.fail('Takes too much time: ' + (endTime - startTime)); + }, MAX_RENDERING_TIME); - startTime = performance.now(); + startTime = performance.now(); - Plotly.newPlot(gd, mock); + Plotly.newPlot(gd, mock); + }); }); - }); + } }); }); From c8dd83b6c9e99f7c0733b3ae2f7f11ba6381d812 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Thu, 26 Jun 2025 18:12:49 -0400 Subject: [PATCH 39/46] run each tests case in isolation --- tasks/test_performance.js | 46 ++++++----- test/jasmine/performance_tests/all_test.js | 81 ++----------------- .../performance_tests/assets/post_process.js | 2 +- .../performance_tests/assets/test_cases.js | 74 +++++++++++++++++ 4 files changed, 106 insertions(+), 97 deletions(-) create mode 100644 test/jasmine/performance_tests/assets/test_cases.js diff --git a/tasks/test_performance.js b/tasks/test_performance.js index 26b2cc83a1f..c1485dd71a2 100644 --- a/tasks/test_performance.js +++ b/tasks/test_performance.js @@ -13,27 +13,33 @@ var pathToJasminePerformanceTests = constants.pathToJasminePerformanceTests; * * $ npm run test-jasmine -- --performanceTest= */ + +var testCases = require('../test/jasmine/performance_tests/assets/test_cases').testCases; + glob(pathToJasminePerformanceTests + '/*.js').then(function(files) { - var tasks = files.map(function(file) { - return function(cb) { - var cmd = [ - 'karma', 'start', - path.join(constants.pathToRoot, 'test', 'jasmine', 'karma.conf.js'), - '--performanceTest=' + path.basename(file), - '--nowatch', - '--tracesType=scattergl', - '--tracesMode=markers', - '--tracesCount=1', - '--tracesPoints=1000', - ].join(' '); - - console.log('Running: ' + cmd); - - exec(cmd, function(err) { - cb(null, err); - }).stdout.pipe(process.stdout); - }; - }); + var tasks = []; + for(let file of files) { + for(let testCase of testCases) { + tasks.push(function(cb) { + var cmd = [ + 'karma', 'start', + path.join(constants.pathToRoot, 'test', 'jasmine', 'karma.conf.js'), + '--performanceTest=' + path.basename(file), + '--nowatch', + '--tracesType=' + testCase.traceType, + '--tracesMode=' + testCase.mode, + '--tracesCount=' + testCase.nTraces, + '--tracesPoints=' + testCase.n, + ].join(' '); + + console.log('Running: ' + cmd); + + exec(cmd, function(err) { + cb(null, err); + }).stdout.pipe(process.stdout); + }); + } + } runSeries(tasks, function(err, results) { if(err) throw err; diff --git a/test/jasmine/performance_tests/all_test.js b/test/jasmine/performance_tests/all_test.js index 46b73d348e2..54d8f646881 100644 --- a/test/jasmine/performance_tests/all_test.js +++ b/test/jasmine/performance_tests/all_test.js @@ -3,6 +3,7 @@ var delay = require('../assets/delay'); var d3SelectAll = require('../../strict-d3').selectAll; var Plotly = require('../../../lib/index'); var downloadCSV = require('./assets/post_process').downloadCSV; +var tests = require('./assets/test_cases').testCases; var nSamples = require('./assets/constants').nSamples; var MAX_RENDERING_TIME = 4000; @@ -10,78 +11,6 @@ var gd = createGraphDiv(); const samples = Array.from({ length: nSamples }, (_, i) => i); -var tests = []; - -for(let traceType of ['image', 'heatmap', 'contour']) { - for(let m of [10, 20, 40, 80, 160, 320, 640]) { - let nx = 5 * m; - let ny = 2 * m; - tests.push({ - nx: nx, - ny: ny, - n: nx * ny, - nTraces: 1, - traceType: traceType, - selector: traceType === 'image' ? 'g.imagelayer.mlayer' : - 'g.' + traceType + 'layer' - }); - } -} - -for(let traceType of ['box', 'violin']) { - for(let mode of ['no points', 'all points']) { - for(let nTraces of [1, 10, 100]) { - for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { - tests.push({ - n:n, - nTraces: nTraces, - traceType: traceType, - mode: mode, - selector: ( - traceType === 'box' ? 'g.trace.boxes' : - traceType === 'violin' ? 'g.trace.violins' : - undefined - ) - }); - } - } - } -} - -for(let traceType of ['scatter', 'scattergl', 'scattergeo']) { - for(let mode of ['markers', 'lines', 'markers+lines']) { - for(let nTraces of [1, 10, 100]) { - for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { - tests.push({ - n:n, - nTraces: nTraces, - traceType: traceType, - mode: mode, - selector: ( - traceType === 'scatter' ? 'g.trace.scatter' : - undefined - ) - }); - } - } - } -} - -for(let traceType of ['bar', 'histogram']) { - for(let mode of ['group', 'stack', 'overlay']) { - for(let nTraces of [1, 10, 100]) { - for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { - tests.push({ - n:n, - nTraces: nTraces, - traceType: traceType, - mode: mode, - selector: 'g.trace.bars' - }); - } - } - } -} function generateMock(spec) { var type = spec.traceType; @@ -161,17 +90,17 @@ function makeBox(spec) { for(var k = 0; k < spec.nTraces; k++) { var trace = { type: spec.traceType, - boxpoints: spec.mode === 'all points' ? 'all' : false, + boxpoints: spec.mode === 'all_points' ? 'all' : false, y: y.slice(k * nPerTrace, (k + 1) * nPerTrace), x: Array.from({ length: nPerTrace }, (_, i) => k) }; if(spec.traceType === 'box') { - trace.boxpoints = spec.mode === 'all points' ? 'all' : false; + trace.boxpoints = spec.mode === 'all_points' ? 'all' : false; } if(spec.traceType === 'violin') { - trace.points = spec.mode === 'all points' ? 'all' : false; + trace.points = spec.mode === 'all_points' ? 'all' : false; } data.push(trace); @@ -283,8 +212,8 @@ describe('Performance test various traces', function() { if(testCase) { if(testCase.tracesType && testCase.tracesType !== spec.traceType) testIt = false; if(testCase.tracesCount && testCase.tracesCount !== spec.nTraces) testIt = false; - if(testCase.tracesMode && testCase.tracesMode !== spec.mode) testIt = false; if(testCase.tracesPoints && testCase.tracesPoints !== spec.n) testIt = false; + if((testCase.tracesMode !== 'undefined' && testCase.tracesMode) && testCase.tracesMode !== spec.mode) testIt = false; } if(testIt) { diff --git a/test/jasmine/performance_tests/assets/post_process.js b/test/jasmine/performance_tests/assets/post_process.js index 225b67d1e08..71158f3ba78 100644 --- a/test/jasmine/performance_tests/assets/post_process.js +++ b/test/jasmine/performance_tests/assets/post_process.js @@ -28,7 +28,7 @@ exports.downloadCSV = function(allTests) { var myBlob = new Blob([str], {type: 'text/plain'}) var url = window.URL.createObjectURL(myBlob); a.href = url; - a.download = 'all.csv'; + a.download = 'results.csv'; a.style.display = 'none'; document.body.append(a); a.click(); diff --git a/test/jasmine/performance_tests/assets/test_cases.js b/test/jasmine/performance_tests/assets/test_cases.js new file mode 100644 index 00000000000..b8f24b0f145 --- /dev/null +++ b/test/jasmine/performance_tests/assets/test_cases.js @@ -0,0 +1,74 @@ +var tests = []; + +for(let traceType of ['image', 'heatmap', 'contour']) { + for(let m of [10, 20, 40, 80, 160, 320, 640]) { + let nx = 5 * m; + let ny = 2 * m; + tests.push({ + nx: nx, + ny: ny, + n: nx * ny, + nTraces: 1, + traceType: traceType, + selector: traceType === 'image' ? 'g.imagelayer.mlayer' : + 'g.' + traceType + 'layer' + }); + } +} + +for(let traceType of ['box', 'violin']) { + for(let mode of ['no_points', 'all_points']) { + for(let nTraces of [1, 10, 100]) { + for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { + tests.push({ + n:n, + nTraces: nTraces, + traceType: traceType, + mode: mode, + selector: ( + traceType === 'box' ? 'g.trace.boxes' : + traceType === 'violin' ? 'g.trace.violins' : + undefined + ) + }); + } + } + } +} + +for(let traceType of ['scatter', 'scattergl', 'scattergeo']) { + for(let mode of ['markers', 'lines', 'markers+lines']) { + for(let nTraces of [1, 10, 100]) { + for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { + tests.push({ + n:n, + nTraces: nTraces, + traceType: traceType, + mode: mode, + selector: ( + traceType === 'scatter' ? 'g.trace.scatter' : + undefined + ) + }); + } + } + } +} + +for(let traceType of ['bar', 'histogram']) { + for(let mode of ['group', 'stack', 'overlay']) { + for(let nTraces of [1, 10, 100]) { + for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { + tests.push({ + n:n, + nTraces: nTraces, + traceType: traceType, + mode: mode, + selector: 'g.trace.bars' + }); + } + } + } +} + +exports.testCases = tests; From 99e9efd2e25c5de93c585a9c8024352732647f52 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Thu, 26 Jun 2025 19:17:34 -0400 Subject: [PATCH 40/46] organise output files --- .circleci/config.yml | 5 ++++ test/jasmine/performance_tests/all_test.js | 29 +++++++++++++++---- .../performance_tests/assets/post_process.js | 4 +-- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d79afdb0d98..38ce2d5842a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -56,6 +56,11 @@ jobs: - run: name: Display system information command: npm run system-info > ~/Downloads/system_info.txt + - run: + name: Combine CSV files + command: | + head -n 1 `ls ~/Downloads/*.csv | head -n 1` > ~/Downloads/all.csv + tail -n+2 -q ~/Downloads/*.csv >> ~/Downloads/all.csv - store_artifacts: path: ~/Downloads destination: / diff --git a/test/jasmine/performance_tests/all_test.js b/test/jasmine/performance_tests/all_test.js index 54d8f646881..c62bb15306c 100644 --- a/test/jasmine/performance_tests/all_test.js +++ b/test/jasmine/performance_tests/all_test.js @@ -198,8 +198,10 @@ function makeScatterGeo(spec) { describe('Performance test various traces', function() { 'use strict'; + var filename; + afterAll(function(done) { - downloadCSV(tests); + downloadCSV(tests, filename); // delay for the download to be completed delay(1000)().then(done) }); @@ -209,11 +211,28 @@ describe('Performance test various traces', function() { var testCase = __karma__.config.testCase; + filename = ''; + if(testCase) { - if(testCase.tracesType && testCase.tracesType !== spec.traceType) testIt = false; - if(testCase.tracesCount && testCase.tracesCount !== spec.nTraces) testIt = false; - if(testCase.tracesPoints && testCase.tracesPoints !== spec.n) testIt = false; - if((testCase.tracesMode !== 'undefined' && testCase.tracesMode) && testCase.tracesMode !== spec.mode) testIt = false; + if(testCase.tracesType) { + filename += testCase.tracesType; + if(testCase.tracesType !== spec.traceType) testIt = false; + } + + if(testCase.tracesMode && testCase.tracesMode !== 'undefined') { + filename += '_' + testCase.tracesMode; + if(testCase.tracesMode !== spec.mode) testIt = false; + } + + if(testCase.tracesPoints) { + filename += '_' + testCase.tracesPoints; + if(testCase.tracesPoints !== spec.n) testIt = false; + } + + if(testCase.tracesCount) { + filename += '_' + testCase.tracesCount; + if(testCase.tracesCount !== spec.nTraces) testIt = false; + } } if(testIt) { diff --git a/test/jasmine/performance_tests/assets/post_process.js b/test/jasmine/performance_tests/assets/post_process.js index 71158f3ba78..5e40729dc45 100644 --- a/test/jasmine/performance_tests/assets/post_process.js +++ b/test/jasmine/performance_tests/assets/post_process.js @@ -1,4 +1,4 @@ -exports.downloadCSV = function(allTests) { +exports.downloadCSV = function(allTests, filename) { var str = [ 'number of traces', 'chart type', @@ -28,7 +28,7 @@ exports.downloadCSV = function(allTests) { var myBlob = new Blob([str], {type: 'text/plain'}) var url = window.URL.createObjectURL(myBlob); a.href = url; - a.download = 'results.csv'; + a.download = (filename || 'results') + '.csv'; a.style.display = 'none'; document.body.append(a); a.click(); From d92d35647198426f6b19205eae9f2c26a88e7888 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Thu, 26 Jun 2025 20:23:53 -0400 Subject: [PATCH 41/46] test extra points --- .../performance_tests/assets/test_cases.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/test/jasmine/performance_tests/assets/test_cases.js b/test/jasmine/performance_tests/assets/test_cases.js index b8f24b0f145..a0dda662c9f 100644 --- a/test/jasmine/performance_tests/assets/test_cases.js +++ b/test/jasmine/performance_tests/assets/test_cases.js @@ -1,7 +1,7 @@ var tests = []; for(let traceType of ['image', 'heatmap', 'contour']) { - for(let m of [10, 20, 40, 80, 160, 320, 640]) { + for(let m of [10, 20, 40, 80, 160, 320, 640, 1280]) { let nx = 5 * m; let ny = 2 * m; tests.push({ @@ -16,10 +16,13 @@ for(let traceType of ['image', 'heatmap', 'contour']) { } } +var allN = [/*1000, 2000, 4000, 8000, 16000, */32000, 64000, 128000]; +var allNTraces = [1/*, 10, 100*/] + for(let traceType of ['box', 'violin']) { for(let mode of ['no_points', 'all_points']) { - for(let nTraces of [1, 10, 100]) { - for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { + for(let nTraces of allNTraces) { + for(let n of allN) { tests.push({ n:n, nTraces: nTraces, @@ -38,8 +41,8 @@ for(let traceType of ['box', 'violin']) { for(let traceType of ['scatter', 'scattergl', 'scattergeo']) { for(let mode of ['markers', 'lines', 'markers+lines']) { - for(let nTraces of [1, 10, 100]) { - for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { + for(let nTraces of allNTraces) { + for(let n of allN) { tests.push({ n:n, nTraces: nTraces, @@ -57,8 +60,8 @@ for(let traceType of ['scatter', 'scattergl', 'scattergeo']) { for(let traceType of ['bar', 'histogram']) { for(let mode of ['group', 'stack', 'overlay']) { - for(let nTraces of [1, 10, 100]) { - for(let n of [1000, 2000, 4000, 8000, 16000, 32000]) { + for(let nTraces of allNTraces) { + for(let n of allN) { tests.push({ n:n, nTraces: nTraces, From a98fd66eaaa004729c693ee9883e505112611d11 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Thu, 26 Jun 2025 20:44:35 -0400 Subject: [PATCH 42/46] revise test setup --- test/jasmine/performance_tests/assets/test_cases.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jasmine/performance_tests/assets/test_cases.js b/test/jasmine/performance_tests/assets/test_cases.js index a0dda662c9f..27f86de551f 100644 --- a/test/jasmine/performance_tests/assets/test_cases.js +++ b/test/jasmine/performance_tests/assets/test_cases.js @@ -16,8 +16,8 @@ for(let traceType of ['image', 'heatmap', 'contour']) { } } -var allN = [/*1000, 2000, 4000, 8000, 16000, */32000, 64000, 128000]; -var allNTraces = [1/*, 10, 100*/] +var allN = [1000, 2000, 4000, 8000, 16000, 32000, 64000, 128000]; +var allNTraces = [1, /*10, */100] for(let traceType of ['box', 'violin']) { for(let mode of ['no_points', 'all_points']) { From ea673bc2d7017d576b645f342e13957579bc3e7a Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Fri, 27 Jun 2025 09:43:20 -0400 Subject: [PATCH 43/46] refactor test --- test/jasmine/performance_tests/all_test.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/jasmine/performance_tests/all_test.js b/test/jasmine/performance_tests/all_test.js index c62bb15306c..e8095ff9f95 100644 --- a/test/jasmine/performance_tests/all_test.js +++ b/test/jasmine/performance_tests/all_test.js @@ -238,9 +238,10 @@ describe('Performance test various traces', function() { if(testIt) { samples.forEach(function(t) { it( - spec.nTraces + ' ' + spec.traceType + + 'All points:' + spec.n + ' | ' + + spec.nTraces + 'X' + spec.traceType + (spec.mode ? ' | mode: ' + spec.mode : '') + - ' | size:' + spec.n + ' | turn: ' + t, function(done) { + ' | turn: ' + t, function(done) { if(t === 0) { tests[index].raw = []; } @@ -250,9 +251,9 @@ describe('Performance test various traces', function() { var startTime, endTime; - requestID1 = requestAnimationFrame(function() { + requestID1 = requestAnimationFrame(() => { // Wait for actual rendering instead of promise - requestID2 = requestAnimationFrame(function() { + requestID2 = requestAnimationFrame(() => { endTime = performance.now(); var delta = endTime - startTime; From 8974efe7579b91d706b26628c63b6517afa9b185 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Fri, 27 Jun 2025 10:34:31 -0400 Subject: [PATCH 44/46] create CSV for failed cases --- tasks/test_performance.js | 60 ++++++++++++++++++- test/jasmine/performance_tests/all_test.js | 2 +- .../performance_tests/assets/post_process.js | 2 +- 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/tasks/test_performance.js b/tasks/test_performance.js index c1485dd71a2..a90a3da833d 100644 --- a/tasks/test_performance.js +++ b/tasks/test_performance.js @@ -1,3 +1,4 @@ +var fs = require('fs'); var path = require('path'); var exec = require('child_process').exec; var { glob } = require('glob'); @@ -5,6 +6,7 @@ var runSeries = require('run-series'); var constants = require('./util/constants'); var pathToJasminePerformanceTests = constants.pathToJasminePerformanceTests; +var pathToRoot = constants.pathToRoot; /** * Run all jasmine 'performance' test in series @@ -42,15 +44,67 @@ glob(pathToJasminePerformanceTests + '/*.js').then(function(files) { } runSeries(tasks, function(err, results) { - if(err) throw err; - var failed = results.filter(function(r) { return r; }); if(failed.length) { console.log('\ntest-performance summary:'); failed.forEach(function(r) { console.warn('- ' + r.cmd + ' failed'); }); console.log(''); - process.exit(1); + + // Create CSV file for failed cases + var str = [ + 'number of traces', + 'chart type & mode', + 'data points', + 'run id', + 'rendering time(ms)' + ].join(',') + '\n'; + + failed.forEach(function(r) { + // split command string frist by space then by equal to get + var cmdArgs = r.cmd.split(' ').map(part => { + return part.split('='); + }); + + var test = {}; + + for(var i = 0; i < cmdArgs.length; i++) { + if('--tracesCount' === cmdArgs[i][0]) { + test.nTraces = cmdArgs[i][1]; + } + } + + for(var i = 0; i < cmdArgs.length; i++) { + if('--tracesType' === cmdArgs[i][0]) { + test.traceType = cmdArgs[i][1]; + } + } + + for(var i = 0; i < cmdArgs.length; i++) { + if('--tracesMode' === cmdArgs[i][0]) { + test.mode = cmdArgs[i][1]; + } + } + + for(var i = 0; i < cmdArgs.length; i++) { + if('--tracesPoints' === cmdArgs[i][0]) { + test.n = cmdArgs[i][1]; + } + } + + str += [ + (test.nTraces || 1), + (test.traceType + (test.mode ? ' ' + test.mode : '')), + test.n, + 'failed', + '' + ].join(',') + '\n'; + }); + + var failedCSV = pathToRoot + '../../../Downloads/failed.csv'; + console.log('Saving:', failedCSV) + console.log(str); + fs.writeFileSync(failedCSV, str); } }); }); diff --git a/test/jasmine/performance_tests/all_test.js b/test/jasmine/performance_tests/all_test.js index e8095ff9f95..f61039b0a6a 100644 --- a/test/jasmine/performance_tests/all_test.js +++ b/test/jasmine/performance_tests/all_test.js @@ -239,7 +239,7 @@ describe('Performance test various traces', function() { samples.forEach(function(t) { it( 'All points:' + spec.n + ' | ' + - spec.nTraces + 'X' + spec.traceType + + spec.nTraces + ' X ' + spec.traceType + (spec.mode ? ' | mode: ' + spec.mode : '') + ' | turn: ' + t, function(done) { if(t === 0) { diff --git a/test/jasmine/performance_tests/assets/post_process.js b/test/jasmine/performance_tests/assets/post_process.js index 5e40729dc45..940dae12d67 100644 --- a/test/jasmine/performance_tests/assets/post_process.js +++ b/test/jasmine/performance_tests/assets/post_process.js @@ -1,7 +1,7 @@ exports.downloadCSV = function(allTests, filename) { var str = [ 'number of traces', - 'chart type', + 'chart type & mode', 'data points', 'run id', 'rendering time(ms)' From 0f80d1b15a4fb1692af08b78d7b1a09fc279ba37 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Fri, 27 Jun 2025 13:11:55 -0400 Subject: [PATCH 45/46] fix Download path --- tasks/test_performance.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/test_performance.js b/tasks/test_performance.js index a90a3da833d..c029ae5fc61 100644 --- a/tasks/test_performance.js +++ b/tasks/test_performance.js @@ -101,7 +101,7 @@ glob(pathToJasminePerformanceTests + '/*.js').then(function(files) { ].join(',') + '\n'; }); - var failedCSV = pathToRoot + '../../../Downloads/failed.csv'; + var failedCSV = pathToRoot + '../Downloads/failed.csv'; console.log('Saving:', failedCSV) console.log(str); fs.writeFileSync(failedCSV, str); From ae35d0095393d312dce70a278d021b8d5db08f9a Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Wed, 2 Jul 2025 14:12:00 -0400 Subject: [PATCH 46/46] test data points between 64K to 128K with 1K step --- .../performance_tests/assets/test_cases.js | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/test/jasmine/performance_tests/assets/test_cases.js b/test/jasmine/performance_tests/assets/test_cases.js index 27f86de551f..3605321ac47 100644 --- a/test/jasmine/performance_tests/assets/test_cases.js +++ b/test/jasmine/performance_tests/assets/test_cases.js @@ -1,5 +1,6 @@ var tests = []; +/* for(let traceType of ['image', 'heatmap', 'contour']) { for(let m of [10, 20, 40, 80, 160, 320, 640, 1280]) { let nx = 5 * m; @@ -15,12 +16,23 @@ for(let traceType of ['image', 'heatmap', 'contour']) { }); } } +*/ -var allN = [1000, 2000, 4000, 8000, 16000, 32000, 64000, 128000]; -var allNTraces = [1, /*10, */100] +function fillArrayFromToBy(start, end, step) { + const result = []; + for (let i = start; i <= end; i += step) { + result.push(i); + } + return result; +} + +//var allN = [1000, 2000, 4000, 8000, 16000, 32000, 64000, 128000]; +var allN = fillArrayFromToBy(64000, 128000, 1000); +//var allNTraces = [1, /*10, */100] +var allNTraces = [1] -for(let traceType of ['box', 'violin']) { - for(let mode of ['no_points', 'all_points']) { +for(let traceType of [/*'box', */'violin']) { + for(let mode of [/*'no_points', */'all_points']) { for(let nTraces of allNTraces) { for(let n of allN) { tests.push({ @@ -40,7 +52,7 @@ for(let traceType of ['box', 'violin']) { } for(let traceType of ['scatter', 'scattergl', 'scattergeo']) { - for(let mode of ['markers', 'lines', 'markers+lines']) { + for(let mode of [/*'markers', 'lines', */'markers+lines']) { for(let nTraces of allNTraces) { for(let n of allN) { tests.push({ @@ -58,8 +70,8 @@ for(let traceType of ['scatter', 'scattergl', 'scattergeo']) { } } -for(let traceType of ['bar', 'histogram']) { - for(let mode of ['group', 'stack', 'overlay']) { +for(let traceType of ['bar'/*, 'histogram'*/]) { + for(let mode of ['group'/*, 'stack', 'overlay'*/]) { for(let nTraces of allNTraces) { for(let n of allN) { tests.push({ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy