Tibrogargan
Tibrogargan

Reputation: 4603

Determing Effect of Optimization

Disclaimer: This question uses jQuery for an example, but is not about jQuery.

Is there a way to determine how the compiler optimizes a certain piece of code?

For instance, assuming someCollection.size() is invariant, this code:

for (var i = 0; i < someCollection.size(); i++) ...

In more recent compilers, should get optimized to something more like this:

var _unnamed = someCollection.size();
for (var i = 0; i < _unnamed; i++) ...

So writing this code yourself gives you no value (and may be less readable).

Recently, I wanted to see how using arrow functions would affect performance. Theoretically, they could be faster than the equivalent normal function since they have less overhead (they don't bind a number of things). I used this as a test case:

$('.someClass').each( (undefined, value) => { doSomething($(value)); } );

And an equivalent using a "normal" function:

$('.someClass').each( function() { doSomething($(this)); } );

Each method was run a few thousand times, first the arrow function and then the normal function and I was surprised to see that the arrow function was consistently slightly slower. To be fair, I then ran the normal function first and the result was reversed, the normal function was slower. It didn't seem to matter which function was run first - it would always be slower. Once I started arbitrarily running one method of the function first and throwing away those results the rest of the results became very similar.

My assumption is that there is some optimization being done in the first test that is affecting the results of the subsequent tests.

My question is: How can I find out what the optimizer is doing so I can determine if any particular optimization actually has an effect?

Upvotes: 1

Views: 44

Answers (1)

Thomas
Thomas

Reputation: 12637

For instance, assuming someCollection.size() is invariant, this code:

Current JS Engines are not able to determine that someCollection.size() is invariant, so they are not able to perform this optimization. And this method is highly unlikely to be inlined (this would allow mentioned optimization).

You're calling a function, this function could do pretty much anything, so no certainties here at all.

My question is: How can I find out what the optimizer is doing so I can determine if any particular optimization actually has an effect?

Currently, we have 3/4 major JS engines in the field:

  • V8 in Chrome & Opera
  • Chakra in Edge
  • SpiderMonkey in FF
  • And I'm not entirely sure what Apple's using, whether they migrated to V8, or still use Nitro.
    Anyway, in my experience, Safari's performance differs to Chrome.

You could expect that each of these basically use the same optimization techniques, but since you can experience differences in performance you can also conclude that they apply them differently.

My Conclusion here: you're chasing a ghost / premature optimization

Even if you'd show a distinct function it would be impossible to determine the final optimizations applied by the any of these JIT-compilers since it also depends on data collected from the particular calls of this function and the passed values. So one function may be optimized in different ways on different calls of your site, just through different usage.

Take a look at this: Vyacheslav Egorov - LXJS 2013 - Performance and benchmarking

Not an answer to this question but maybe a few insights why this whole question (as it is) is a waste of time.

Upvotes: 2

Related Questions