-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
module.exports = {} approach and objects with fast / slow properties #11430
Comments
Considering that it takes nanoseconds to access them, I wonder if this improvement is visible at all. |
@indutny ... in the benchmarks that I have run, there has been an average improvement of about 5% when switching, particularly on modules that are frequently used. |
I just wanted to add that using |
@indutny If I get it right, it takes nanoseconds if a user imports a separate property or a method, like |
Hmm, it is strange. It seems all the imported core modules are fast objects: require('repl')._builtinLibs.forEach((name) => {
const mod = require(name);
const keyNum = Reflect.ownKeys(mod).length;
console.log(`${name}: ${%HasFastProperties(mod) ? 'fast' : 'slow'} (${keyNum} keys)`);
});
Maybe v8 somehow optimizes them before/after importing or in another time. |
@joyeecheung Oh, I see. Thank you. It seems the limit of fast non-keyed incrementation is 133 keys: Test (click me):const obj = {};
obj.x001 = 0;
obj.x002 = 0;
obj.x003 = 0;
obj.x004 = 0;
obj.x005 = 0;
obj.x006 = 0;
obj.x007 = 0;
obj.x008 = 0;
obj.x009 = 0;
obj.x010 = 0;
obj.x011 = 0;
obj.x012 = 0;
obj.x013 = 0;
obj.x014 = 0;
obj.x015 = 0;
obj.x016 = 0;
obj.x017 = 0;
obj.x018 = 0;
obj.x019 = 0;
obj.x020 = 0;
obj.x021 = 0;
obj.x022 = 0;
obj.x023 = 0;
obj.x024 = 0;
obj.x025 = 0;
obj.x026 = 0;
obj.x027 = 0;
obj.x028 = 0;
obj.x029 = 0;
obj.x030 = 0;
obj.x031 = 0;
obj.x032 = 0;
obj.x033 = 0;
obj.x034 = 0;
obj.x035 = 0;
obj.x036 = 0;
obj.x037 = 0;
obj.x038 = 0;
obj.x039 = 0;
obj.x040 = 0;
obj.x041 = 0;
obj.x042 = 0;
obj.x043 = 0;
obj.x044 = 0;
obj.x045 = 0;
obj.x046 = 0;
obj.x047 = 0;
obj.x048 = 0;
obj.x049 = 0;
obj.x050 = 0;
obj.x051 = 0;
obj.x052 = 0;
obj.x053 = 0;
obj.x054 = 0;
obj.x055 = 0;
obj.x056 = 0;
obj.x057 = 0;
obj.x058 = 0;
obj.x059 = 0;
obj.x060 = 0;
obj.x061 = 0;
obj.x062 = 0;
obj.x063 = 0;
obj.x064 = 0;
obj.x065 = 0;
obj.x066 = 0;
obj.x067 = 0;
obj.x068 = 0;
obj.x069 = 0;
obj.x070 = 0;
obj.x071 = 0;
obj.x072 = 0;
obj.x073 = 0;
obj.x074 = 0;
obj.x075 = 0;
obj.x076 = 0;
obj.x077 = 0;
obj.x078 = 0;
obj.x079 = 0;
obj.x080 = 0;
obj.x081 = 0;
obj.x082 = 0;
obj.x083 = 0;
obj.x084 = 0;
obj.x085 = 0;
obj.x086 = 0;
obj.x087 = 0;
obj.x088 = 0;
obj.x089 = 0;
obj.x090 = 0;
obj.x091 = 0;
obj.x092 = 0;
obj.x093 = 0;
obj.x094 = 0;
obj.x095 = 0;
obj.x096 = 0;
obj.x097 = 0;
obj.x098 = 0;
obj.x099 = 0;
obj.x100 = 0;
obj.x101 = 0;
obj.x102 = 0;
obj.x103 = 0;
obj.x104 = 0;
obj.x105 = 0;
obj.x106 = 0;
obj.x107 = 0;
obj.x108 = 0;
obj.x109 = 0;
obj.x110 = 0;
obj.x111 = 0;
obj.x112 = 0;
obj.x113 = 0;
obj.x114 = 0;
obj.x115 = 0;
obj.x116 = 0;
obj.x117 = 0;
obj.x118 = 0;
obj.x119 = 0;
obj.x120 = 0;
obj.x121 = 0;
obj.x122 = 0;
obj.x123 = 0;
obj.x124 = 0;
obj.x125 = 0;
obj.x126 = 0;
obj.x127 = 0;
obj.x128 = 0;
obj.x129 = 0;
obj.x130 = 0;
obj.x131 = 0;
obj.x132 = 0;
obj.x133 = 0;
console.log(%HasFastProperties(obj));
obj.x134 = 0;
console.log(%HasFastProperties(obj));
But actually this is another limit here: limit of the overall number of keys: var o1 = {};
var o2 = {};
for (var i = 1; %HasFastProperties(o2); i++) {
o1['p' + i] = 1;
o2 = JSON.parse(JSON.stringify(o1));
}
console.log(Object.keys(o2).length);
|
Sorry, I will close it as not relevant for this case. |
There were some PRs recently that refactor
module.exports
filling from incremental to atomic.There also were some concerns about the gain of this approach.
It came to pass that I've recently read some stuff about v8 optimization concerning objects. There is a distinction between objects with fast and slow properties, and one way to make an object slow is exactly incremental property definition.
So I've written a simple test to define how many added properties make an object slow:
Then I've run this code with some Node.js versions:
You could also check this code in the some last Node.js:
This is also a double benchmark, with benchmark.js and a naive approach:
I am not completely sure this should be considered as a reason for the mentioned refactoring, but I feel somehow obliged to share this data.
cc @nodejs/v8
The text was updated successfully, but these errors were encountered: