You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm opening it as a draft as there are a lot of loose ends to solve before considering such usage. This is an experiment related to research I'm conducting.
The idea is to generate a benchmark coverage for all of our exported modules. For instance, check if the functions exposed by require('node:fs') are covered in our benchmark suite (benchmark/fs/*.js). To achieve an intermediary goal I had to monkey-patch the Module.prototype.require before executing each benchmark (we run each one in a separate process) to return a singleton that basically manages the state of how many times that function was called.
I have tried to use our test_runner coverage for that, but it couldn't identify the location of built-in modules (require('node:*')) which is expected by the nature of a coverage tool. The other reason it didn't fit was the need to cover only the exported modules, not the lib/internal/* functions. The result I wanted to have was: "I need to know which functions/classes that are exposed to users do not contain a benchmark".
It's also worth it to mention that, a nested call is ignored in the benchmark report. Example:
For each benchmark file I require coverage.js to set up the monkey patch of Module.require (-r ./coverage.js). However, any benchmark setup would impact the report. For instance:
constbench=common.createBenchmark(main,{ ... }});constfs=require('node:fs')constfiles=fs.readdir(...)// readdir and collect filesfunctionmain({ ... }){bench.start()for(constfileoffiles){fs.existsSync(file)}bench.end(files.length)}
This will result in:
fs.existsSync status "covered"
fs.readdir status "covered"
This is unfortunate, as in reality only fs.existsSync is being measured. One theory that came to my mind to fix that is to intercept the bench.start calls and only then return the patched modules. I might try it later.
For simplicity, I'm assuming that all modules export an object containing functions. However, some modules default exports a function, for instance, typeof require('node:assert') === 'function'. This also means that classes such as AsyncLocalStorage (or function classes) aren't covered as the constructor (called with new ..) isn't patched. I think using Proxy might solve it, but I haven't tested yet.
I'm certain there's a better way to approach this goal and fix the limitations. Hence, I'm opening it as a draft.
nodejs-github-bot
added
benchmark
Issues and PRs related to Node.js benchmarks and benchmarking infrastructure.
performance
Issues and PRs related to the performance of Node.js.
url
Issues and PRs related to the legacy built-in url module.
whatwg-url
Issues and PRs related to the WHATWG URL implementation.
labels
Aug 12, 2024
That requires changing all benchmarks and this is subject to developer errors. I tried to do it harmlessly (funny saying that while I'm monkey patching Module.require). But, possibly simpler than my approach.
That requires changing all benchmarks and this is subject to developer errors. I tried to do it harmlessly (funny saying that while I'm monkey patching Module.require). But, possibly simpler than my approach.
We can add an eslint rule (possibly @aduh95) to call that parameter inside bench.run() and bench.end() scope.
This pull request has been marked as stale due to 90 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.
github-actionsBot
added
the
stale
Issues and PRs marked stale due to inactivity and scheduled for automatic closure.
label
Jul 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
benchmarkIssues and PRs related to Node.js benchmarks and benchmarking infrastructure.performanceIssues and PRs related to the performance of Node.js.staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.urlIssues and PRs related to the legacy built-in url module.whatwg-urlIssues and PRs related to the WHATWG URL implementation.
5 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hey,
I'm opening it as a draft as there are a lot of loose ends to solve before considering such usage. This is an experiment related to research I'm conducting.
The idea is to generate a benchmark coverage for all of our exported modules. For instance, check if the functions exposed by
require('node:fs')are covered in our benchmark suite (benchmark/fs/*.js). To achieve an intermediary goal I had to monkey-patch theModule.prototype.requirebefore executing each benchmark (we run each one in a separate process) to return a singleton that basically manages the state of how many times that function was called.I have tried to use our
test_runnercoverage for that, but it couldn't identify the location of built-in modules (require('node:*')) which is expected by the nature of a coverage tool. The other reason it didn't fit was the need to cover only the exported modules, not thelib/internal/*functions. The result I wanted to have was: "I need to know which functions/classes that are exposed to users do not contain a benchmark".It's also worth it to mention that, a nested call is ignored in the benchmark report. Example:
fs.existscallsfs.accessbehind the scenesnode/lib/fs.js
Line 260 in b8a2550
fs.existsandfs.accessas "covered" in the benchmark report. It should only countfs.existsas covered.benchmark/**/*.jsResults
Details
Full result: https://gist.github.com/RafaelGSS/66d33091560d61932b26d74af2fa8b82
Current limitations
coverage.jsto set up the monkey patch ofModule.require(-r ./coverage.js). However, any benchmark setup would impact the report. For instance:This will result in:
fs.existsSyncstatus "covered"fs.readdirstatus "covered"This is unfortunate, as in reality only
fs.existsSyncis being measured. One theory that came to my mind to fix that is to intercept thebench.startcalls and only then return the patched modules. I might try it later.typeof require('node:assert') === 'function'. This also means that classes such asAsyncLocalStorage(or function classes) aren't covered as the constructor (called withnew ..) isn't patched. I think usingProxymight solve it, but I haven't tested yet.I'm certain there's a better way to approach this goal and fix the limitations. Hence, I'm opening it as a draft.
cc: @nodejs/benchmarking @nodejs/test_runner @lemire