matter-js icon indicating copy to clipboard operation
matter-js copied to clipboard

Straight forward JS rewriting of solveVelocity method to improve performance

Open bchevalier opened this issue 7 years ago • 4 comments

Results

Before screen shot 2017-11-20 at 3 51 00 pm

After screen shot 2017-11-20 at 3 50 51 pm

Observed speed up for that method is: 1 - (86.39 - 11.25) / (87.32 - 6.80) * 6.80 / 11.25 = 43.6%

Overall speed up is roughly 5% in general. Speed-up seems consistent on all the tests. I never encountered a test where the solveVelocity method takes up 70% of the total resources though, as observed by @photonstorm.

bchevalier avatar Dec 03 '17 14:12 bchevalier

Hi @bchevalier,

I'm interested in making this engine faster. I tried your solution but honestly I didn't find any performance improvements :(

This is how I tested it (very handmade): https://codepen.io/tylercorleone/pen/vYJjpaW

Essentially copy/paste the JS in the console on the https://brm.io/matter-js/demo page.

It will run 5 times with the "official" method and 5 with your.

Can you check it out?

Thanks

skylupop avatar Nov 08 '21 15:11 skylupop

I was able to obtain a reliable result with my test code, here what came out: (I intentionally alternated the standard and new code tests)

Short version:

standard Resolver.solveVelocity: 17.70% 
new Resolver.solveVelocity proposal: 31.77%
standard Resolver.solveVelocity: 16.28%
new Resolver.solveVelocity proposal: 39.50% 
standard Resolver.solveVelocity: 14.49% 
new Resolver.solveVelocity proposal: 40.41% `

Full result:

ragdoll-test.txt

I run this test on the ragdoll example on Firefox, setting the privacy.reduceTimerPrecision conig to false (https://developer.mozilla.org/en-US/docs/Web/API/Performance/now#reduced_time_precision) in order to obtain more precision. Just copy-paste the code on: https://codepen.io/tylercorleone/pen/vYJjpaW :)

skylupop avatar Nov 09 '21 01:11 skylupop

Hi @skylupop

If I remember properly I think this PR mainly consists in saving time to perform property accessed by saving results to local variables. And looking at the changes it is hard to imagine how the existing version could be strictly better.

First, a few words on why there could be a difference in the results:

  • It is possible that JS compilers got better since this PR was submitted.
  • It is also possible that some JS compilers do a better job on the version suggested here and some other compilers do better on the existing version.

Here are a few things I noticed that could be the root of issues with the testing methodology you mentioned:

  • I would recommend making performance tests on Chrome. I used Chrome for all my testings, its JS engine is much faster than Firefox's and I would consider it more advanced on top of being much more widely used and being similar to Safari in terms of performance and JS performance behavior and identical to Edge (because it uses the Chrome JS engines). So testing on Chrome is similar to testing for 90% of users, while testing on Firefox is like testing for less than 4% of the users.
  • You should try out intensive test cases, the ragdoll test is not one of them, "lightweight" tests can involve too much noise in the data and make some overhead operations more impactful than they are when the physics engine is used intensively.
  • The solveVelocity method actually calls some vector functions in but I do not see those in the profile log. Here I would need more info on how the profile log was generated.

bchevalier avatar Nov 09 '21 06:11 bchevalier

Hi @bchevalier ,

I partially found the cause of the problem of my result.

My test basically creates a backup of the "standard" Resolver.solveVelocity function, defines your function and then run the example from 0 to a certain tick (e.g. 600) first using the default solveVelocity function then using your, etc.

I found that comparing your version with the minified/combined/i-dont-know-what default version lead to those results. What's on the minified version that makes it go that faster once already downloaded and hopefully JIT compiled? That is, in order to obtain comparable results I had (and this is the part I didn't understand) to "override" the default solveVelocity, simply using the non minified code (why?!). I preferred to override the entire Matter's definitions in order to compare apples with apples...

I replicated the exact same problem using Chrome's performance tool.

Btw... that's what I obtained:

Stress example on Chrome:

default Resolver.solveVelocity (2400 samples): 302 ms (18.0%)
new Resolver.solveVelocity (2400 samples): 195 ms (11.7%)
default Resolver.solveVelocity (2400 samples): 326 ms (18.3%)
new Resolver.solveVelocity (2400 samples): 183 ms (11.2%)
default Resolver.solveVelocity (2400 samples): 285 ms (17.8%)
new Resolver.solveVelocity (2400 samples): 157 ms (10.6%)

That is ~ 41.4% faster

Complete results:

stress-test_chrome.txt

Same example on Firefox:

default Resolver.solveVelocity (2400 samples): 518 ms (24.0%)
new Resolver.solveVelocity (2400 samples): 432 ms (20.1%)
default Resolver.solveVelocity (2400 samples): 526 ms (23.3%)
new Resolver.solveVelocity (2400 samples): 385 ms (19.4%)
default Resolver.solveVelocity (2400 samples): 432 ms (24.7%)
new Resolver.solveVelocity (2400 samples): 359 ms (21.9%)

That is ~ 20.3% faster

Complete results:

stress-test_firefox.txt

@liabru any chance to work on this? :)

skylupop avatar Nov 10 '21 01:11 skylupop