run-unit.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #!/usr/bin/env node
  2. var progress = require('progress');
  3. var fs = require('fs');
  4. var nWarmup = 2;
  5. var nRepeats = 32 + nWarmup;
  6. var path = require('path');
  7. var prevResults = {};
  8. try {
  9. var r = require('./results.json');
  10. r.forEach(function(rr) {
  11. prevResults[rr.path] = rr
  12. });
  13. } catch(e) {
  14. // no prev results?
  15. }
  16. function stats(times) {
  17. var avg = 0;
  18. for(var i=0; i < times.length; ++i) {
  19. avg += times[i]/times.length;
  20. }
  21. var v = 0;
  22. for(var i=0; i < times.length; ++i) {
  23. v += (times[i] - avg)*(times[i] - avg) / times.length;
  24. }
  25. var stdev = Math.sqrt(v);
  26. return {
  27. avg: avg,
  28. stdev: stdev,
  29. stdevrel: stdev/avg
  30. };
  31. }
  32. function runFolder(name, done) {
  33. fs.readdir(name, function(err, list) {
  34. if (err)
  35. return done(err);
  36. runFileList(name, list, done);
  37. });
  38. }
  39. function benchmarkModule(m, modulePath, done) {
  40. var results = [];
  41. var bar = new progress(m.comment + ' [:bar] ', {
  42. total: nRepeats,
  43. clear: true
  44. });
  45. function repeat(w, n) {
  46. bar.tick();
  47. if (n === 0) {
  48. var result = {};
  49. var s = stats(results);
  50. var unsDigits = Math.floor(Math.floor(s.stdev).toString().length * 0.8);
  51. var pow = Math.pow(10, unsDigits);
  52. var avg = Math.round(s.avg / pow)*pow;
  53. var uns = Math.round(s.stdev / pow)*pow;
  54. console.log('%s: %s ±%s', m.comment, avg, uns);
  55. result.time = s.avg;
  56. result.timeStdev = s.stdev;
  57. result.comment = m.comment;
  58. result.path = path.relative(__dirname, modulePath);
  59. if (m.toSpeed) {
  60. var speed = m.toSpeed(s.avg, s.stdev);
  61. var speedDigits = Math.floor(Math.floor(speed.error).toString().length * 0.8);
  62. pow = Math.pow(10, speedDigits);
  63. console.log(' = %s ±%s %s',
  64. Math.round(speed.value / pow)*pow,
  65. Math.round(speed.error / pow)*pow, speed.units);
  66. var prev = prevResults[result.path];
  67. if (prev) {
  68. if (speed.value > prev.speed.value + prev.speed.error) {
  69. console.log('Faster then prev result: %s ±%s %s', prev.speed.value, prev.speed.units)
  70. } else if (speed.value < prev.speed.value - prev.speed.error) {
  71. console.log('Slower then prev result: %s ±%s %s', prev.speed.value, prev.speed.units)
  72. }
  73. }
  74. result.speed = speed;
  75. }
  76. return done(null, result);
  77. }
  78. var start = process.hrtime();
  79. setImmediate(function() {
  80. m(function() {
  81. var end = process.hrtime(start);
  82. if (w <= 0)
  83. results.push(end[0]*1e9 + end[1]);
  84. repeat(w-1, n-1);
  85. });
  86. });
  87. }
  88. repeat(nWarmup-1, nRepeats-1, done);
  89. }
  90. function runFileList(base, list, done) {
  91. var index = -1;
  92. var results;
  93. function runOne(err, res) {
  94. if (err) return done(err);
  95. ++index;
  96. if (res) {
  97. if (!results)
  98. results = [];
  99. if (Array.isArray(res))
  100. results = results.concat(res);
  101. else
  102. results.push(res);
  103. }
  104. if (index >= list.length) {
  105. return done(null, results);
  106. }
  107. var fname = base + '/' + list[index];
  108. fs.stat(fname, function(err, stat) {
  109. if (err) return done(err);
  110. if (stat.isDirectory())
  111. return runFolder(fname, runOne);
  112. else if (fname.slice(-3) == '.js') {
  113. var m = require(fname);
  114. return benchmarkModule(m, fname, runOne);
  115. }
  116. runOne();
  117. });
  118. }
  119. runOne();
  120. }
  121. //var name = process.argv[2] || __dirname + '/unit';
  122. runFolder(__dirname + '/unit', function(err, results) {
  123. //console.log(results);
  124. fs.writeFileSync(__dirname + '/results.json', JSON.stringify(results));
  125. });