-
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
lib: prefer using Array#includes instead of Array#indexOf #26568
Comments
Assuming you tested the equivalent of master, did you also check the versioned branches? It may/may not be as fast in older versions of V8. |
I've tested it on LTS version (code). Here is the result: Node.js 6.17.0 (
Node.js 8.15.1 (same):
Node.js 10.15.3 (
Node.js 11.11.0 (
So we may not land this change into 6.x. |
@starkwang the actual code is optimized away in your benchmark. Therefore it is significantly faster. |
I do not think we should change this ever. |
const items = [
'jpg', '3fr', 'ari', 'arw',
'bay', 'crw', 'cr2', 'cap',
'data', 'dcs', 'dcr', 'dng',
'drf', 'eip', 'erf', 'fff',
'iiq', 'k25', 'kdc', 'mdc',
'mef', 'mos', 'mrw', 'nef',
'nrw', 'obm', 'orf', 'pef',
'ptx', 'pxn', 'r3d', 'raf',
'raw', 'rwl', 'rw2', 'rwz',
'sr2', 'srf', 'srw', 'tif',
'x3f'
];
const searchStrings = [
'raf',
'nef',
'cr'
];
function indexOf(arr, str) {
if (arr.indexOf(str) !== -1)
return 1;
return 0;
}
function includes(arr, str) {
if (arr.includes(str))
return 1;
return 0;
}
function bench(fn) {
console.time(fn.name);
let count = 0;
for (var i = 0; i < 1e7; i++) {
count += fn(items, searchStrings[i % searchStrings.length]);
}
console.timeEnd(fn.name);
console.log(count);
}
for (var i = 0; i < 3; i++) {
bench(indexOf);
bench(includes);
} Yields on master:
|
just for the record, includes is actually much simpler in the spec. indexOf does a HasProperty before each Get, while includes just goes straight to Get. the difference is negligible |
@devsnek you are right, I remembered the spec wrong in this case (I remembered it the other way around). However, in most cases the V8 7.3 seems to be on par performance wise. |
For such a tiny op, depend on the use case, IMHO we should always prefer readability, simplicity, and explicivity. If the usage is to simply test for inclusion, and there is no use of the found index, then One main reason for this is that our stdlib is used as a reference implementation. https://jsperf.com/array-indexof-vs-includes/25 that indicate +/- 10% on my chrome's V8 7.2 |
PR-URL: nodejs#26732 Refs: nodejs#26568 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
In our lib code, we are still using
Array#indexOf
to determine if an item is existed in array.For example:
node/lib/url.js
Line 584 in 3414bc7
node/lib/internal/util/inspect.js
Line 273 in b05fd4b
For semantics, I think it's more appropriate to move them into
Array#includes
and it seems no performance difference between them at present: https://jsperf.com/array-indexof-vs-includes.The text was updated successfully, but these errors were encountered: