I am curious about the performance of assigning the same element to itself. Is V8 smart enough to understand this should not be executed?
obj.key = obj.key;
The use case would be something like.
Object.keys(otherObj).forEach(e => {
if(!obj[e]) {
obj[e] = foo();
}
});
If we use a ternary operator instead of if-statement, would there be a penalty performance?
Object.keys(otherObj).forEach(e => obj[e] = obj[e] ? obj[e] : foo());
V8 developer here. I don't think there's a case where obj[e] = obj[e]
assignments will be optimized away. Deciding that such an optimization would be valid requires so much knowledge about obj
and e
that checking for all that would in most cases be too expensive to be worth it.
As Bergi points out, obj[e] = (... ? obj[e] : ...)
is conceptually significantly more complicated and therefore even less likely to ever be optimized away, even if you assume that we'll spend a couple more years improving V8.
Regarding obj.key
vs obj[e]
(for both loading and storing), if they both see only one object shape and only one property name, they'll have pretty much the same performance. If [e]
sees more than one property name (like in your example looping over Object.keys()
), it will be somewhat slower; however .key
isn't really an alternative there -- it's precisely the flexibility of [e]
that makes it slower. If either of them sees more than one shape for obj
, they'll be slower than otherwise, with [e]
taking a bigger hit than .key
; this will e.g. be the case when your loop ends up adding properties that weren't there before.
All that said, any performance differences are probably too small to matter, and my recommendation is to write the code that's most readable -- or run your own measurements to figure out with certainty whether there's a measurable difference in your case. Keep in mind that microbenchmarks are often misleading; use an app that comes as close as possible to your production environment for such tests.