-2

Please note: This question is purely hypothetical and for learning purposes. I do not plan on making unnecessary micro-optimizations.

From research that I've done, it seems that using for-in loops are relatively slow compared to other loops. For example, this loop:

const obj = { a: 'a', b: 'b', c: 'c', ... };

for (key in obj) {
  const val = obj[key];
}

is approximately 7 times slower on average than this loop:

const arr = [ 'a', 'b', 'c', ... ];

for (let i = 0; i < arr.length; i++) {
  const val = arr[i];
}

My alternate solution to using for-in is to make an array of keys that I can iterate over with a numeric for loop, then look up those keys in the object.

I'm wondering, would this be a better solution (purely in terms of raw performance) than the for-in loop:

const keys = [ 'a', 'b', 'c', ... ]
const obj = { a: 'a', b: 'b', c: 'c', ... }

for (let i = 0; i < keys.length; i++) {
  const val = obj[keys[i]];
}
  • "*is approximately 7 times slower on average than this loop*" but the two are very different. Why compare them? One uses an array, the other an object. Different data structures. And different loops: `for-in` goes through the prototype chain. You're not doing proper scientific enquiry, as you're not controlling the (experiment) variables here. – VLAZ Sep 19 '22 at 21:43
  • 1
    "*would this be a better solution (purely in terms of raw performance)*" [Which is faster?](https://ericlippert.com/2012/12/17/performance-rant/) – VLAZ Sep 19 '22 at 21:43
  • @VLAZ I'm not comparing the loops themselves or the data structures, I'm just comparing the performance between the two. In this case, I'm trying to come up with a solution closer to the performance of the numeric for than the for-in. – WillWillington Sep 19 '22 at 21:49
  • 1
    https://stackoverflow.com/questions/13488751/why-is-for-in-slow-in-javascript – James Sep 19 '22 at 21:50
  • "*I'm not comparing the loops themselves or the data structures,*" correct, you're comparing *multiple* things all at once. Your experiment varies several parameters at the same time. – VLAZ Sep 19 '22 at 21:53
  • @VLAZ I respect your input but the way I see it I'm only considering one parameter here: preformance. If this is like apples and oranges, then I'm asking: If an apple weighs A and an orange weighs B, which fruit gives me a weight closer to A? – WillWillington Sep 19 '22 at 21:57

1 Answers1

0

Thanks to VLAZ's wonderful support I was able to figure it out after asking elsewhere. The other individual recommended Benchmark.js to me and I concluded that the numeric for w/ lookup keys is roughly 10 times faster than for-in for large data.

Data size:

const iterations = 1000000;

const obj = {};
for (let i = 0; i < iterations; i++) {
  obj1['s' + i] = 1;
}

const arr = [];
for (let i = 0; i < iterations; i++) {
  arr[i] = 's' + i;
}

for-in benchmark:

for (key in obj) {
  const v = obj[key];
}

Completed in: ~0.3174 seconds

numeric for w/ lookup:

for (let i = 0; i < arr.length; i++) {
  const v = obj[arr[i]];
}

Completed in: ~0.0396 seconds

  • 3
    Notice that this benchmark is [pretty meaningless since the code doesn't actually *do* anything](https://mrale.ph/blog/2012/12/15/microbenchmarks-fairy-tale.html) – Bergi Sep 19 '22 at 22:51
  • @Bergi What would you recommend in terms of structuring this benchmark? I'm pretty new to benchmarking so any tips would be appreciated. I just figured running the loops themselves would test their performance, is this not the case unless they're preforming some operations? – WillWillington Sep 19 '22 at 22:55
  • I'd write `let count = 0; …loop… { const v = …; count += v; } window.someGlobal = count;` – Bergi Sep 19 '22 at 22:59
  • @Bergi Cool, I'll implement something like this and play around with it in the benchmark tests. Thank you! – WillWillington Sep 19 '22 at 23:02