staticOrDynamic.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // Comparing the difference of compiled adhoc vs compiled in runtime function execution
  2. // This should let build functions specific to dimension, without affecting performance.
  3. var Benchmark = require('benchmark');
  4. var suite = new Benchmark.Suite;
  5. let bodies;
  6. let total = 0;
  7. let srcCode = staticCompiled.toString().split('\n').slice(1, -1).join('\n');
  8. let dynamicCompiled = compile(srcCode);
  9. resetBodies();
  10. suite.add('static compiled', function() {
  11. for (var i = 0; i < 2000; ++i) {
  12. if (staticCompiled(bodies, 0.5, 0) > 0) {
  13. total = 1;
  14. }
  15. }
  16. })
  17. .add('dynamic pre-compiled', function() {
  18. for (var i = 0; i < 2000; ++i) {
  19. if (dynamicCompiled(bodies, 0.5, 0) > 0) {
  20. total = 1;
  21. }
  22. }
  23. })
  24. .add('dynamic ad-hoc pre-compiled', function() {
  25. let fn = compile(srcCode);
  26. for (var i = 0; i < 2000; ++i) {
  27. if (fn(bodies, 0.5, 0) > 0) {
  28. total = 1;
  29. }
  30. }
  31. })
  32. .on('cycle', function(event) {
  33. console.log(String(event.target), total);
  34. total = 0;
  35. resetBodies();
  36. })
  37. .on('complete', function() {
  38. console.log('Fastest is ' + this.filter('fastest').pluck('name'));
  39. })
  40. // run async
  41. .run({ 'async': true });
  42. function resetBodies() {
  43. bodies = [];
  44. for (let i = 0; i < 100; ++i) {
  45. bodies.push(createBody(i));
  46. }
  47. }
  48. function createBody(i) {
  49. return {
  50. springCount: 0,
  51. springLength: 10,
  52. mass: 1,
  53. force: {x: i, y: i},
  54. velocity: {x: 0, y: 0},
  55. pos: {x: i, y: i}
  56. };
  57. }
  58. function staticCompiled(bodyCollection, timeStep, adaptiveTimeStepWeight) {
  59. var dx = 0, tx = 0,
  60. dy = 0, ty = 0,
  61. i,
  62. max = bodyCollection.length;
  63. if (max === 0) {
  64. return 0;
  65. }
  66. for (i = 0; i < max; ++i) {
  67. var body = bodyCollection[i];
  68. if (adaptiveTimeStepWeight && body.springCount) {
  69. timeStep = (adaptiveTimeStepWeight * body.springLength/body.springCount);
  70. }
  71. var coefficient = timeStep / body.mass;
  72. body.velocity.x += coefficient * body.force.x;
  73. body.velocity.y += coefficient * body.force.y;
  74. var vx = body.velocity.x,
  75. vy = body.velocity.y,
  76. v = Math.sqrt(vx * vx + vy * vy);
  77. if (v > 1) {
  78. // We normalize it so that we move within timeStep range.
  79. // for the case when v <= 1 - we let velocity to fade out.
  80. body.velocity.x = vx / v;
  81. body.velocity.y = vy / v;
  82. }
  83. dx = timeStep * body.velocity.x;
  84. dy = timeStep * body.velocity.y;
  85. body.pos.x += dx;
  86. body.pos.y += dy;
  87. tx += Math.abs(dx); ty += Math.abs(dy);
  88. }
  89. return (tx * tx + ty * ty)/max;
  90. }
  91. function compile(body) {
  92. return new Function('bodies', 'timeStep', 'adaptiveTimeStepWeight', body);
  93. }