Skip to content

Instantly share code, notes, and snippets.

@tiagoamaro
Last active April 2, 2020 21:43
Show Gist options
  • Save tiagoamaro/566fe6f217832132fddf to your computer and use it in GitHub Desktop.
Save tiagoamaro/566fe6f217832132fddf to your computer and use it in GitHub Desktop.
JS safe navigation functions benchmark
import Benchmark from "benchmark";
import _ from "lodash";
// Source: http://codereview.stackexchange.com/questions/72253/safe-navigating-function-for-nested-object-properties
// Thanks to elclanrs
Object.reduce_attr = function (obj, props) {
return props.split('.').reduce(function(acc, p) {
if (acc === null) { return; }
return acc[p];
}, obj);
};
// Source: https://gist.github.com/jgornick/3785996
// Thanks to Joe Gornick
Object.walk = function (object, path) {
if (typeof path == 'string') {
path = path.split('.');
}
for (var i = 0, len = path.length; i < len; i++) {
if (!object || typeof (object = object[path[i]]) == 'undefined') {
object = undefined;
break;
}
}
return object;
};
var suite = new Benchmark.Suite();
var nested_object = { a: {b: {c: 2} } };
suite
.add('Object.walk found', () => {
return Object.walk(nested_object, 'a.b.c');
})
.add('Object.walk not found', () => {
return Object.walk(nested_object, 'a.b.nothing');
})
.add('Object.reduce_attr found', () => {
return Object.reduce_attr(nested_object, 'a.b.c');
})
.add('Object.reduce_attr not found', () => {
return Object.reduce_attr(nested_object, 'a.b.nothing');
})
.add('Use && found', () => {
return nested_object && nested_object.a && nested_object.a.b && nested_object.a.b.c;
})
.add('Use && not found', () => {
return nested_object && nested_object.a && nested_object.a.b && nested_object.a.b.nothing;
})
.add('Lodash _.get found', () => {
return _.get(nested_object, 'a.b.c');
})
.add('Lodash _.get not found', () => {
return _.get(nested_object, 'a.b.nothing');
})
.add('Optional chain proposal ES proposal, found', () => { // (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining)
return nested_object?.a?.b?.c;
})
.add('Optional chain proposal ES proposal, not found', () => {
return nested_object?.a?.b?.nothing;
})
.on('cycle', function(event) {
console.log(String(event.target));
})
.run({ 'async': true });
// Results:
// Object.walk found x 8,371,227 ops/sec ±0.97% (87 runs sampled)
// Object.walk not found x 8,188,517 ops/sec ±1.13% (90 runs sampled)
// Object.reduce_attr found x 8,237,625 ops/sec ±1.04% (87 runs sampled)
// Object.reduce_attr not found x 8,696,140 ops/sec ±1.15% (90 runs sampled)
// Use && found x 1,230,748,485 ops/sec ±0.36% (94 runs sampled)
// Use && not found x 1,230,533,147 ops/sec ±0.37% (96 runs sampled)
// Lodash _.get found x 5,162,706 ops/sec ±1.06% (91 runs sampled)
// Lodash _.get not found x 4,998,263 ops/sec ±1.16% (87 runs sampled)
// Optional chain proposal ES proposal, found x 1,198,367,029 ops/sec ±0.27% (91 runs sampled)
// Optional chain proposal ES proposal, not found x 1,215,718,566 ops/sec ±0.31% (94 runs sampled)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment