Skip to content

Instantly share code, notes, and snippets.

@flekschas
Created July 31, 2018 14:59
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flekschas/5aad97d1c2520db7af0a9623deec005f to your computer and use it in GitHub Desktop.
Save flekschas/5aad97d1c2520db7af0a9623deec005f to your computer and use it in GitHub Desktop.
Performance of Object.keys vs Object.values for getting the number of props of an object

Results

Let's get started!
VM73:13 Object.keys took: 20234.000000054948msecs
VM73:19 Object.values took: 5987.800000002608msecs

Conclusion

It turns out that Object.values is about 3.2 times faster than Object.keys in Chrome v67.

Note: Things might change in the future and I've only tested it in Chrome really, so take the results with a grain of salt!

((numProps, propsLength, numIter) => {
let obj = {};
for (let p = 0; p < numProps; p++) {
obj[p] = String(p) * propsLength;
}
console.log("Let's get started!");
let t0 = performance.now();
for (let p = 0; p < numIter; p++){
let val = Object.keys(obj).length;
}
let t01 = performance.now();
console.log("Object.keys took: " + (performance.now() - t0) + "msecs");
t0 = performance.now();
for (let p = 0; p < numIter; p++){
let val = Object.values(obj).length;
}
console.log("Object.values took: " + (performance.now() - t0) + "msecs");
})(1000, 1, 1000000);
@mlodato517
Copy link

mlodato517 commented Apr 12, 2019

I don't know much about V8 or node or anything, but I ran these locally and I think it's because you used numeric keys so V8 treated it similarly to an array so Object.values().length was similar to array.length
I ran:

((numProps, propsLength, numIter) => {
  const performance = require('perf_hooks').performance

  let obj = {};
  for (let p = 0; p < numProps; p++) {
    obj[p] = String(p) * propsLength; // numeric keys, sort of an "array"
  }
  let obj2 = {};
  for (let p = 0; p < numProps; p++) {
    obj2[`key${p}`] = String(p) * propsLength; // string keys
  }
  console.log("Let's get started!");

  let t0 = performance.now();
  for (let p = 0; p < numIter; p++){
    let val = Object.keys(obj).length;
  }
  console.log("Object.keys took: " + (performance.now() - t0) + " ms for numeric keys");

  t0 = performance.now();
  for (let p = 0; p < numIter; p++){
    let val = Object.values(obj).length;
  }
  console.log("Object.values took: " + (performance.now() - t0) + " ms for numeric keys");

  t0 = performance.now();
  for (let p = 0; p < numIter; p++){
    let val = Object.keys(obj2).length;
  }
  console.log("Object.keys took: " + (performance.now() - t0) + " ms for string keys");

  t0 = performance.now();
  for (let p = 0; p < numIter; p++){
    let val = Object.values(obj2).length;
  }
  console.log("Object.values took: " + (performance.now() - t0) + " ms for string keys");
})(1000, 1, 10000);

on node v11.10.1 and got:

Object.keys took: 134.7211339995265 ms for numeric keys
Object.values took: 24.43546699732542 ms for numeric keys
Object.keys took: 502.20294899865985 ms for string keys
Object.values took: 1579.1671300008893 ms for string keys

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment