-
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: use Object.create(null) for dictionary object #3791
Conversation
Fixes #3788 `arrayToHash()` needs to use `Object.create(null)` for its dictionary object.
Could use a test |
Note: |
See also: #728 |
Probably better would be to special-case |
@@ -159,7 +159,7 @@ function stylizeNoColor(str, styleType) { | |||
|
|||
|
|||
function arrayToHash(array) { | |||
var hash = {}; | |||
var hash = Object.create(null); | |||
|
|||
array.forEach(function(val, idx) { | |||
hash[val] = true; |
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.
You'd check if val
was __proto__
here and discard it if it was, I think. cc @bnoordhuis
add if val is `__proto__`, use `Object.create(null);`
|
||
array.forEach(function(val, idx) { | ||
|
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.
Why creating a new hash in each iteration?
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.
@pmq20 Sorry, it was a mistake
@JungMinu please run |
Also rebasing multiple commits into one in a single MR is more preferable. |
if array contains __proto__, use Object.create(null)
also make sure you follow coding style (spaces, braces, etc.) |
Beautify codes
hash = Object.create(null); | ||
} else { | ||
hash = {}; | ||
} | ||
|
||
array.forEach(function(val, idx) { |
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.
if idx
is not used, why pass it?
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.
@YuriSolovyov Hmm, It was there before I made a PR,
I speculate that it could be used
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 is not used anywhere in the scope of the function, IMO it is safe to drop it
@Fishrock123 @JungMinu Sorry for the confusion here. Let's simply set |
util: use Object.create(null) for dictionary object
Fair enough. My bad. |
LGTM |
if CI is happy, LGTM |
LGTM. Good to know that we may be able to use this in other place in the code too. |
|
||
array.forEach(function(val, idx) { | ||
array.forEach(function(val) { |
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.
Would we want to continue to use arrow functions for inline anons?
array.forEach(val => hash[val] = true);
and/or convert this into a single reduce expression?
function arrayToHash(array) {
return array.reduce((acc, val) => {
acc[val] = true;
return acc;
}, Object.create(null));
}
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.
Using reduce()
is a bit misleading since nothing is actually being reduced, and I don't think turning it into a single expression is helpful in this case.
As for using arrow functions, personally only think they must be used to prevent var self = this;
from happening, but also wouldn't be opposed if it were used. IOW, if it does change then cool, but it's not a blocker.
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.
Ok cool. Yeah I guess I agree, the naming of Array.prototype.reduce
is definitely a bit awkward here. Maybe the general arrow function stance is also worth a larger style/convention conversation elsewhere? Thanks for the input!
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.
Ironically @JungMinu has already started some of this :) #3622
Hopefully we'll be able to finish conversion of other applicable cases, but it's not high priority. Don't think the CTC would feel the need to make a stance "official" but if the rest of the code is following some convention then we can point to that as an example going forward.
CI: https://ci.nodejs.org/job/node-test-pull-request/710/ (Continuous Integration test run) |
@@ -159,9 +159,9 @@ function stylizeNoColor(str, styleType) { | |||
|
|||
|
|||
function arrayToHash(array) { | |||
var hash = {}; | |||
var hash = Object.create(null);; |
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.
This adds a redundant semicolon.
CI is red but failures look unrelated. |
@JungMinu .. can I ask you to please squash the commits? |
I just used this script to compare the performance. 'use strict';
const times = 10e6;
console.time('Object.create');
for (var i = 0; i < times; i += 1) {
let obj = Object.create(null);
}
console.timeEnd('Object.create');
console.time('Object Literal');
for (var i = 0; i < times; i += 1) {
let obj = {};
}
console.timeEnd('Object Literal'); And it looks like |
@jasnell Sure, I will squash the commits soon :) |
Thank you!
|
@thefourtheye If you look at the IR generated by the optimizing compiler you'll find much of the second call has been optimized out completely. Also, if you look at actual execution time you'll see that the savings is in the low double digit nanoseconds. The call is sufficiently fast for how it's used here. |
@trevnorris Yup, the difference is not pronounced much. Probably, I'll have a shot at #2350 again. |
@jasnell @trevnorris Thanks a lot 😄 |
@@ -159,9 +159,9 @@ function stylizeNoColor(str, styleType) { | |||
|
|||
|
|||
function arrayToHash(array) { | |||
var hash = {}; | |||
var hash = Object.create(null); |
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.
Why not a Set
instead?
@jasnell @trevnorris Sorry, because of the conflicts in my branch, I submitted a new PR, #3831 |
has anyone tested |
Fixes #3788
arrayToHash()
needs to useObject.create(null)
for its dictionary object.