profile.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // Gathers statistical data, and provides them in convinient form
  2. "use strict";
  3. var partial = require("es5-ext/function/#/partial")
  4. , forEach = require("es5-ext/object/for-each")
  5. , pad = require("es5-ext/string/#/pad")
  6. , compact = require("es5-ext/array/#/compact")
  7. , d = require("d")
  8. , memoize = require("./plain");
  9. var max = Math.max, stats = exports.statistics = {};
  10. Object.defineProperty(
  11. memoize,
  12. "__profiler__",
  13. d(function (conf) {
  14. var id, source, data, stack;
  15. stack = new Error().stack;
  16. if (
  17. !stack ||
  18. !stack.split("\n").slice(3).some(function (line) {
  19. if (line.indexOf("/memoizee/") === -1 && line.indexOf(" (native)") === -1) {
  20. source = line.replace(/\n/g, "\\n").trim();
  21. return true;
  22. }
  23. return false;
  24. })
  25. ) {
  26. source = "unknown";
  27. }
  28. id = compact.call([conf.profileName, source]).join(", ");
  29. if (!stats[id]) stats[id] = { initial: 0, cached: 0 };
  30. data = stats[id];
  31. conf.on("set", function () { ++data.initial; });
  32. conf.on("get", function () { ++data.cached; });
  33. })
  34. );
  35. exports.log = function () {
  36. var initial, cached, ordered, ipad, cpad, ppad, toPrc, log;
  37. initial = cached = 0;
  38. ordered = [];
  39. toPrc = function (initialCount, cachedCount) {
  40. if (!initialCount && !cachedCount) {
  41. return "0.00";
  42. }
  43. return ((cachedCount / (initialCount + cachedCount)) * 100).toFixed(2);
  44. };
  45. log = "------------------------------------------------------------\n";
  46. log += "Memoize statistics:\n\n";
  47. forEach(
  48. stats,
  49. function (data, name) {
  50. initial += data.initial;
  51. cached += data.cached;
  52. ordered.push([name, data]);
  53. },
  54. null,
  55. function (nameA, nameB) {
  56. return (
  57. this[nameB].initial +
  58. this[nameB].cached -
  59. (this[nameA].initial + this[nameA].cached)
  60. );
  61. }
  62. );
  63. ipad = partial.call(pad, " ", max(String(initial).length, "Init".length));
  64. cpad = partial.call(pad, " ", max(String(cached).length, "Cache".length));
  65. ppad = partial.call(pad, " ", "%Cache".length);
  66. log +=
  67. ipad.call("Init") +
  68. " " +
  69. cpad.call("Cache") +
  70. " " +
  71. ppad.call("%Cache") +
  72. " Source location\n";
  73. log +=
  74. ipad.call(initial) +
  75. " " +
  76. cpad.call(cached) +
  77. " " +
  78. ppad.call(toPrc(initial, cached)) +
  79. " (all)\n";
  80. ordered.forEach(function (data) {
  81. var name = data[0];
  82. data = data[1];
  83. log +=
  84. ipad.call(data.initial) +
  85. " " +
  86. cpad.call(data.cached) +
  87. " " +
  88. ppad.call(toPrc(data.initial, data.cached)) +
  89. " " +
  90. name +
  91. "\n";
  92. });
  93. log += "------------------------------------------------------------\n";
  94. return log;
  95. };