0

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());
asked Apr 19, 2018 at 8:39
6
  • 1
    What was the result of your benchmark ? Commented Apr 19, 2018 at 8:40
  • obj[e] = obj[e] is different from obj[e] = (... ? obj[e] : ...). Which one are you asking about? Commented Apr 19, 2018 at 10:48
  • For what reason would you ever prefer that possibly-slow and totally unreadable construct over a simple for (const e in otherObj) if (!obj[e]) obj[e] = foo();? Commented Apr 19, 2018 at 10:49
  • Notice that is cannot be treated as a no-op when a getter/setter property is involved, so V8 would at least have to always check for that. Commented Apr 19, 2018 at 10:51
  • 1
    @IvoSabev No, not in the regard that both would be a no-op. (Of course a dynamic property assignment/lookup is always slower than a static one). Both should be optimised in the same way - which mostly depends on what obj is. Commented Apr 19, 2018 at 14:40

1 Answer 1

1

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.

answered Apr 19, 2018 at 18:21

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.