Strange JS Performance Issues

I am having problems with my string distance function running too slow. I narrowed it down to the following (time to compare strings 10K):

// desired behavior - 400ms dp[c + 257] = Math.min(dp[c + 256] + 1, dp[c + 1] + 1, dp[c] + (a[i] != b[j])); // this is somewhat faster - 300ms dp[c + 257] = Math.min(dp[c + 256] + 1, dp[c + 1] + 1); dp[c + 257] = Math.min(dp[c + 257], dp[c] + (a[i] != b[j])); // even faster - 50ms dp[c + 257] = Math.min(dp[c + 256] + 1, dp[c + 1] + 1); dp[c + 257] = Math.min(dp[c + 257], dp[c] + (a[i] != b[j] ? 1 : 0)); 

So, first of all, splitting Math.min into two calls is faster than using it once with three arguments - how is this possible? Secondly, why is adding an explicit tertiary expression much faster than relying on an implicit conversion from bool to int?

Here's the script: https://jsfiddle.net/6bnLvbt6/

+5
source share
1 answer

You have 3 test cases:

  • Math.min with arguments 3 of type cast (bool to int)
  • 2 Math.min calls with arguments 2 , where the second call has a type listing
  • 2 Math.min calls with arguments 2 , without types

There is also another difference between 1 and 2 and 3, where on some arguments there is an extra + 1 . I think this is a mistake.

The implicit type of throw seems to be the most expensive. If you remove the implicit type cast from 1 , you will get:

 dp[c + 257] = Math.min(dp[c + 1], dp[c + 256], dp[c] + (a[i] != b[j] ? 1 : 0)); 

It takes 250ms (vs 60ms for 3). This still shows that Math.min with three arguments is slower. Let me explore more.

If you simplify the test case:

 // 1 for(var i = 0; i < 10000; i += 1) { Math.min(1, 2, 3); } // 2 for(var i = 0; i < 10000; i += 1) { Math.min(1, 2); Math.min(1, 3); } 

Results on my machine: 1 takes 2500ms , 2 takes 87ms . If you add more arguments to Math.min , you will see that it gently increases in time by 500ms for each additional argument, this shows something about the implementation.

Browser providers optimize features that are often used. If Math.min with more than two arguments is unusual, these results are not strange. What you see here is that Math.min has two implementations: one for two arguments, which is really well optimized, and the other for more arguments, which is not optimized. For v8, this is confirmed by apsillers: the v8 source on github

+2
source

Source: https://habr.com/ru/post/1235814/


All Articles