-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
util: fix inspect performance bug #20007
Conversation
In case an object contained a circular reference `Object.keys` was called even though it was not necessary at all. This caused a significant overhead for objects that contained a lot of such entries.
@@ -445,6 +445,11 @@ function formatValue(ctx, value, recurseTimes, ln) { | |||
} | |||
} | |||
|
|||
// Using an array here is actually better for the average case than using | |||
// a Set. `seen` will only check for the depth and will never grow too large. | |||
if (ctx.seen.indexOf(value) !== -1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.includes()
unless it has a performance penalty?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It had a performance penalty the last time I checked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indexOf
should be much faster than anything else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it is a case for @nodejs/v8 performance group to look into then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I would love to have/see a benchmark for this.
@mcollina I tested a extreme case: 'use strict';
const util = require('util');
let i = 0;
const obj = {};
while (i++ < 1500) {
obj[i] = {};
}
const circular = {};
for (const k of Object.keys(obj)) {
circular[k] = obj[k];
obj[k].circular = circular;
obj[k].obj = obj;
}
console.time('run');
util.inspect(obj);
console.timeEnd('run');
// Before the patch:
// run: 165971.450ms
// After the patch:
// run: 7377.811ms |
I don't believe this qualifies for fast tracking based on the guidance given in https://github.com/nodejs/node/blob/master/COLLABORATOR_GUIDE.md#waiting-for-approvals. |
Landed in f413f56 |
In case an object contained a circular reference `Object.keys` was called even though it was not necessary at all. This caused a significant overhead for objects that contained a lot of such entries. PR-URL: nodejs#20007 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Trivikram Kamat <[email protected]>
In case an object contained a circular reference `Object.keys` was called even though it was not necessary at all. This caused a significant overhead for objects that contained a lot of such entries. PR-URL: #20007 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Trivikram Kamat <[email protected]>
In case an object contained a circular reference
Object.keys
wascalled even though it was not necessary at all. This caused a
significant overhead for objects that contained a lot of such entries.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes