profilerVisualization.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. function createRow(table, cellName, items) {
  2. var tr = document.createElement('tr');
  3. var res = [];
  4. items.forEach(function(x, i) {
  5. if (x === undefined) {
  6. res.push(null);
  7. return;
  8. }
  9. var td = document.createElement(cellName);
  10. td.textContent = x;
  11. tr.appendChild(td);
  12. res.push(td);
  13. var colspan = 1;
  14. for (var n = i + 1; n < items.length; n++) {
  15. if (items[n] !== undefined) {
  16. break;
  17. }
  18. colspan += 1;
  19. }
  20. if (colspan > 1) {
  21. td.colSpan = colspan;
  22. }
  23. });
  24. table.appendChild(tr);
  25. return res;
  26. }
  27. function showProfile(path, cutoff = 0.05) {
  28. requestGet(path, {}, function(data) {
  29. var table = document.createElement('table');
  30. table.className = 'popup-table';
  31. data.records['total'] = data.total;
  32. var keys = Object.keys(data.records).sort(function(a, b) {
  33. return data.records[b] - data.records[a];
  34. });
  35. var items = keys.map(function(x) {
  36. return {key: x, parts: x.split('/'), time: data.records[x]};
  37. });
  38. var maxLength = items.reduce(function(a, b) {
  39. return Math.max(a, b.parts.length);
  40. }, 0);
  41. var cols = createRow(table, 'th', ['record', 'seconds']);
  42. cols[0].colSpan = maxLength;
  43. function arraysEqual(a, b) {
  44. return !(a < b || b < a);
  45. }
  46. var addLevel = function(level, parent, hide) {
  47. var matching = items.filter(function(x) {
  48. return x.parts[level] && !x.parts[level + 1] && arraysEqual(x.parts.slice(0, level), parent);
  49. });
  50. var sorted = matching.sort(function(a, b) {
  51. return b.time - a.time;
  52. });
  53. var othersTime = 0;
  54. var othersList = [];
  55. var othersRows = [];
  56. var childrenRows = [];
  57. sorted.forEach(function(x) {
  58. var visible = x.time >= cutoff && !hide;
  59. var cells = [];
  60. for (var i = 0; i < maxLength; i++) {
  61. cells.push(x.parts[i]);
  62. }
  63. cells.push(x.time.toFixed(3));
  64. var cols = createRow(table, 'td', cells);
  65. for (i = 0; i < level; i++) {
  66. cols[i].className = 'muted';
  67. }
  68. var tr = cols[0].parentNode;
  69. if (!visible) {
  70. tr.classList.add("hidden");
  71. }
  72. if (x.time >= cutoff) {
  73. childrenRows.push(tr);
  74. } else {
  75. othersTime += x.time;
  76. othersList.push(x.parts[level]);
  77. othersRows.push(tr);
  78. }
  79. var children = addLevel(level + 1, parent.concat([x.parts[level]]), true);
  80. if (children.length > 0) {
  81. var cell = cols[level];
  82. var onclick = function() {
  83. cell.classList.remove("link");
  84. cell.removeEventListener("click", onclick);
  85. children.forEach(function(x) {
  86. x.classList.remove("hidden");
  87. });
  88. };
  89. cell.classList.add("link");
  90. cell.addEventListener("click", onclick);
  91. }
  92. });
  93. if (othersTime > 0) {
  94. var cells = [];
  95. for (var i = 0; i < maxLength; i++) {
  96. cells.push(parent[i]);
  97. }
  98. cells.push(othersTime.toFixed(3));
  99. cells[level] = 'others';
  100. var cols = createRow(table, 'td', cells);
  101. for (i = 0; i < level; i++) {
  102. cols[i].className = 'muted';
  103. }
  104. var cell = cols[level];
  105. var tr = cell.parentNode;
  106. var onclick = function() {
  107. tr.classList.add("hidden");
  108. cell.classList.remove("link");
  109. cell.removeEventListener("click", onclick);
  110. othersRows.forEach(function(x) {
  111. x.classList.remove("hidden");
  112. });
  113. };
  114. cell.title = othersList.join(", ");
  115. cell.classList.add("link");
  116. cell.addEventListener("click", onclick);
  117. if (hide) {
  118. tr.classList.add("hidden");
  119. }
  120. childrenRows.push(tr);
  121. }
  122. return childrenRows;
  123. };
  124. addLevel(0, []);
  125. popup(table);
  126. });
  127. }