From d6f52271445ddca14c936d1885476ff4803c5283 Mon Sep 17 00:00:00 2001 From: Miguel Marcondes Date: Mon, 28 Apr 2025 14:27:39 -0300 Subject: [PATCH 1/3] benchmark: add source map and source map cache --- benchmark/source_map/source-map-cache.js | 66 ++++++++++++++ benchmark/source_map/source-map.js | 97 +++++++++++++++++++++ test/benchmark/test-benchmark-source-map.js | 7 ++ 3 files changed, 170 insertions(+) create mode 100644 benchmark/source_map/source-map-cache.js create mode 100644 benchmark/source_map/source-map.js create mode 100644 test/benchmark/test-benchmark-source-map.js diff --git a/benchmark/source_map/source-map-cache.js b/benchmark/source_map/source-map-cache.js new file mode 100644 index 00000000000000..31f3c7801bf7c8 --- /dev/null +++ b/benchmark/source_map/source-map-cache.js @@ -0,0 +1,66 @@ +'use strict'; + +const common = require('../common.js'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); + +const bench = common.createBenchmark( + main, + { + operation: [ + 'findSourceMap-valid', + 'findSourceMap-generated-source', + ], + n: [1e5], + }, +); + +function main({ operation, n }) { + const Module = require('node:module'); + + Module.setSourceMapsSupport(true, { + generatedCode: true, + }); + const validFileName = path.resolve( + __dirname, + '../../test/fixtures/test-runner/source-maps/line-lengths/index.js', + ); + + const generatedFileName = path.resolve( + __dirname, + '../../test/fixtures/source-map/disk.js', + ); + const generatedFileContent = fs.readFileSync(generatedFileName, 'utf8'); + const sourceMapUrl = path.basename(generatedFileName, '.js') + '.map'; + const sourceWithGeneratedSourceMap = + `${generatedFileContent}\n//# sourceMappingURL=${sourceMapUrl}\n//# sourceURL=${generatedFileName}`; + const generatedExpectedUrl = `file://${path.resolve(generatedFileName)}`; + + let sourceMap; + switch (operation) { + case 'findSourceMap-valid': + require(validFileName); + + bench.start(); + for (let i = 0; i < n; i++) { + sourceMap = Module.findSourceMap(validFileName); + } + bench.end(n); + break; + + case 'findSourceMap-generated-source': + eval(sourceWithGeneratedSourceMap); + + bench.start(); + for (let i = 0; i < n; i++) { + sourceMap = Module.findSourceMap(generatedExpectedUrl); + } + bench.end(n); + break; + + default: + throw new Error(`Unknown operation: ${operation}`); + } + assert.ok(sourceMap); +} diff --git a/benchmark/source_map/source-map.js b/benchmark/source_map/source-map.js new file mode 100644 index 00000000000000..816c1c8e2ba552 --- /dev/null +++ b/benchmark/source_map/source-map.js @@ -0,0 +1,97 @@ +'use strict'; + +const common = require('../common.js'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +const bench = common.createBenchmark( + main, + { + operation: [ + 'parse', + 'parse-sectioned', + 'findEntry', + 'findEntry-sectioned', + 'findOrigin', + 'findOrigin-sectioned', + ], + n: [1e5], + }, +); + +function main({ operation, n }) { + const { SourceMap } = require('node:module'); + + const samplePayload = JSON.parse( + fs.readFileSync( + path.resolve(__dirname, '../../test/fixtures/source-map/no-source.js.map'), + 'utf8', + ), + ); + const sectionedPayload = JSON.parse( + fs.readFileSync( + path.resolve(__dirname, '../../test/fixtures/source-map/disk-index.map'), + 'utf8', + ), + ); + + let sourceMap; + switch (operation) { + case 'parse': + bench.start(); + for (let i = 0; i < n; i++) { + sourceMap = new SourceMap(samplePayload); + } + bench.end(n); + break; + + case 'parse-sectioned': + bench.start(); + for (let i = 0; i < n; i++) { + sourceMap = new SourceMap(sectionedPayload); + } + bench.end(n); + break; + + case 'findEntry': + sourceMap = new SourceMap(samplePayload); + bench.start(); + for (let i = 0; i < n; i++) { + sourceMap.findEntry(i, i); + } + bench.end(n); + break; + + case 'findEntry-sectioned': + sourceMap = new SourceMap(sectionedPayload); + bench.start(); + for (let i = 0; i < n; i++) { + sourceMap.findEntry(i, i); + } + bench.end(n); + break; + + case 'findOrigin': + sourceMap = new SourceMap(samplePayload); + bench.start(); + for (let i = 0; i < n; i++) { + sourceMap.findOrigin(i, i); + } + bench.end(n); + break; + + case 'findOrigin-sectioned': + sourceMap = new SourceMap(sectionedPayload); + bench.start(); + for (let i = 0; i < n; i++) { + sourceMap.findOrigin(i, i); + } + bench.end(n); + break; + + default: + throw new Error(`Unknown operation: ${operation}`); + } + assert.ok(sourceMap); +} diff --git a/test/benchmark/test-benchmark-source-map.js b/test/benchmark/test-benchmark-source-map.js new file mode 100644 index 00000000000000..c4d58b4bdff62c --- /dev/null +++ b/test/benchmark/test-benchmark-source-map.js @@ -0,0 +1,7 @@ +'use strict'; + +require('../common'); + +const runBenchmark = require('../common/benchmark'); + +runBenchmark('source_map', { NODEJS_BENCHMARK_ZERO_ALLOWED: 1 }); From efa9c713ffba71e7413b9a2ae9685becbb7c3306 Mon Sep 17 00:00:00 2001 From: Miguel Marcondes Date: Mon, 23 Jun 2025 17:13:24 -0300 Subject: [PATCH 2/3] benchmark: use fixtures for sourcemap cache --- benchmark/source_map/source-map-cache.js | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/benchmark/source_map/source-map-cache.js b/benchmark/source_map/source-map-cache.js index 31f3c7801bf7c8..3b8a7cb207a6b1 100644 --- a/benchmark/source_map/source-map-cache.js +++ b/benchmark/source_map/source-map-cache.js @@ -2,8 +2,7 @@ const common = require('../common.js'); const assert = require('assert'); -const path = require('path'); -const fs = require('fs'); +const fixtures = require('../../test/common/fixtures'); const bench = common.createBenchmark( main, @@ -22,20 +21,15 @@ function main({ operation, n }) { Module.setSourceMapsSupport(true, { generatedCode: true, }); - const validFileName = path.resolve( - __dirname, - '../../test/fixtures/test-runner/source-maps/line-lengths/index.js', - ); + const validFileName = fixtures.path('test-runner/source-maps/line-lengths/index.js') - const generatedFileName = path.resolve( - __dirname, - '../../test/fixtures/source-map/disk.js', - ); - const generatedFileContent = fs.readFileSync(generatedFileName, 'utf8'); - const sourceMapUrl = path.basename(generatedFileName, '.js') + '.map'; + const fileNameKey = '/source-map/disk.js'; + const generatedFileName = fixtures.path(fileNameKey); + const generatedFileContent = fixtures.readSync(fileNameKey, 'utf8'); + const sourceMapUrl = generatedFileName.replace(/\.js$/, '.map'); const sourceWithGeneratedSourceMap = `${generatedFileContent}\n//# sourceMappingURL=${sourceMapUrl}\n//# sourceURL=${generatedFileName}`; - const generatedExpectedUrl = `file://${path.resolve(generatedFileName)}`; + const generatedExpectedUrl = `file://${generatedFileName}`; let sourceMap; switch (operation) { From c07130481a2b8d2baf9ba46e8eeab6d0cf7c90d7 Mon Sep 17 00:00:00 2001 From: Miguel Marcondes Date: Mon, 23 Jun 2025 17:16:16 -0300 Subject: [PATCH 3/3] benchmark: use fixtures and avoid dead code for sourcemap --- benchmark/source_map/source-map-cache.js | 2 +- benchmark/source_map/source-map.js | 26 +++++++++++------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/benchmark/source_map/source-map-cache.js b/benchmark/source_map/source-map-cache.js index 3b8a7cb207a6b1..aee4155471a02f 100644 --- a/benchmark/source_map/source-map-cache.js +++ b/benchmark/source_map/source-map-cache.js @@ -21,7 +21,7 @@ function main({ operation, n }) { Module.setSourceMapsSupport(true, { generatedCode: true, }); - const validFileName = fixtures.path('test-runner/source-maps/line-lengths/index.js') + const validFileName = fixtures.path('test-runner/source-maps/line-lengths/index.js'); const fileNameKey = '/source-map/disk.js'; const generatedFileName = fixtures.path(fileNameKey); diff --git a/benchmark/source_map/source-map.js b/benchmark/source_map/source-map.js index 816c1c8e2ba552..54f78f300f9746 100644 --- a/benchmark/source_map/source-map.js +++ b/benchmark/source_map/source-map.js @@ -2,8 +2,7 @@ const common = require('../common.js'); const assert = require('assert'); -const fs = require('fs'); -const path = require('path'); +const fixtures = require('../../test/common/fixtures'); const bench = common.createBenchmark( main, @@ -24,19 +23,14 @@ function main({ operation, n }) { const { SourceMap } = require('node:module'); const samplePayload = JSON.parse( - fs.readFileSync( - path.resolve(__dirname, '../../test/fixtures/source-map/no-source.js.map'), - 'utf8', - ), + fixtures.readSync('source-map/no-source.js.map', 'utf8'), ); const sectionedPayload = JSON.parse( - fs.readFileSync( - path.resolve(__dirname, '../../test/fixtures/source-map/disk-index.map'), - 'utf8', - ), + fixtures.readSync('source-map/disk-index.map', 'utf8'), ); let sourceMap; + let sourceMapMethod; switch (operation) { case 'parse': bench.start(); @@ -58,36 +52,40 @@ function main({ operation, n }) { sourceMap = new SourceMap(samplePayload); bench.start(); for (let i = 0; i < n; i++) { - sourceMap.findEntry(i, i); + sourceMapMethod = sourceMap.findEntry(i, i); } bench.end(n); + assert.ok(sourceMapMethod); break; case 'findEntry-sectioned': sourceMap = new SourceMap(sectionedPayload); bench.start(); for (let i = 0; i < n; i++) { - sourceMap.findEntry(i, i); + sourceMapMethod = sourceMap.findEntry(i, i); } bench.end(n); + assert.ok(sourceMapMethod); break; case 'findOrigin': sourceMap = new SourceMap(samplePayload); bench.start(); for (let i = 0; i < n; i++) { - sourceMap.findOrigin(i, i); + sourceMapMethod = sourceMap.findOrigin(i, i); } bench.end(n); + assert.ok(sourceMapMethod); break; case 'findOrigin-sectioned': sourceMap = new SourceMap(sectionedPayload); bench.start(); for (let i = 0; i < n; i++) { - sourceMap.findOrigin(i, i); + sourceMapMethod = sourceMap.findOrigin(i, i); } bench.end(n); + assert.ok(sourceMapMethod); break; default: