Guest User

Untitled

a guest
Oct 17th, 2018
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.43 KB | None | 0 0
  1. /**
  2. * Time execution of a piece of code, with a user-provided number 'iterations'
  3. * of samples (>= 0), or if 'iterations' is null, just one.
  4. */
  5. timeExecution = function(context, code, iterations)
  6. {
  7. var userGiven = true;
  8. if (iterations === null)
  9. {
  10. userGiven = false;
  11. iterations = 1;
  12. }
  13.  
  14. // In FF15 and up, performance.now() provides submillisecond precision;
  15. // for older versions we will have to fall back to Date.now().
  16. var precise = ("performance" in window && "now" in window.performance);
  17.  
  18. // Build up JavaScript code that evaluates and times 'code'.
  19. var getTimingCode = function(code)
  20. {
  21. var nowF = (precise ? "performance.now()" : "Date.now()");
  22. var ret = "{ ";
  23.  
  24. var timingOverhead = "0";
  25. if (precise)
  26. {
  27. // Warm up timer/JavaScript engine. (This helps a tiny bit, I
  28. // think. Can't hurt, at least.)
  29. ret += [nowF, nowF].join("; ") + "; ";
  30. ret += "document.getElementById('dummy'); ";
  31.  
  32. // performance.now() takes some time to run (~0.02ms on my machine);
  33. // thus, save some consecutive timings so we can account for that.
  34. // The actual overhead fluctuates, so use the most reasonable value.
  35. ret += "let __fbt0, __fbt1, __fbt2, __fbt3; ";
  36. ret += "__fbt0 = " + nowF + "; try {} finally { if (__fbt1 = " + nowF + ") {} } ";
  37. ret += "__fbt2 = " + nowF + "; try {} finally { if (__fbt3 = " + nowF + ") {} } ";
  38. timingOverhead = "Math.min(__fbt3 - __fbt2, __fbt1 - __fbt0)";
  39. }
  40. ret += "let __fbT0, __fbT1; __fbT0 = " + nowF + "; ";
  41.  
  42. // Add a default return value, to avoid printing a random float if
  43. // the evaluated code lacks statements.
  44. ret += "void 0; ";
  45.  
  46. // Actually evaluate the code.
  47. ret += "try {\n" + code + "\n} finally {\n";
  48.  
  49. // Save the time taken in window.__fbTiming. To retain the last
  50. // evaluated value for display, wrap the timing calculation/
  51. // assignment in an expression.
  52. ret += "if (__fbT1 = " + nowF + ", window.__fbTiming = (__fbT1 - __fbT0) - " + timingOverhead + ") {} ";
  53.  
  54. ret += "} }";
  55.  
  56. return ret;
  57. };
  58.  
  59. var win = (context.baseWindow ? context.baseWindow : context.window);
  60. var timeCode = getTimingCode(code);
  61.  
  62. var times = [], resArgs;
  63. for (var i = 0; i < iterations; ++i)
  64. {
  65. var save = function() { resArgs = arguments; };
  66. Firebug.CommandLine.evaluate(timeCode, context, context.thisValue,
  67. win, save, save);
  68.  
  69. // Get the timing out from the global.
  70. var timing = NaN;
  71. try
  72. {
  73. timing = +win.wrappedJSObject.__fbTiming;
  74. delete win.wrappedJSObject.__fbTiming;
  75. }
  76. catch (e) {}
  77. times.push(timing);
  78.  
  79. // In case of e.g. syntax errors, we have no data to display. Just
  80. // print the last result/error.
  81. if (isNaN(timing))
  82. {
  83. Firebug.Console.log.apply(Firebug.Console, resArgs);
  84. return;
  85. }
  86. }
  87.  
  88. // Print the result of the last iteration.
  89. Firebug.Console.log.apply(Firebug.Console, resArgs);
  90.  
  91. if (precise && ((times.length >= 5 && times[0] < 0.2) ||
  92. (times.length >= 10 && times[0] < 1.0)))
  93. {
  94. // The first ~3 results are slightly too high, on my machine. Throw
  95. // them away.
  96. times.splice(0, 3);
  97. }
  98.  
  99. if (times.length >= 10)
  100. {
  101. // We have enough data to be able to throw out outliers.
  102. var edge = Math.floor(times.length * 0.2);
  103. times.sort(function(a, b) { return a - b; });
  104. times = times.slice(edge, -edge);
  105. }
  106.  
  107. // Calculate a simple average. If it is negative (from incorrect timing
  108. // overhead correction - most commonly from timing something empty),
  109. // show it as 0 instead.
  110. var average = 0;
  111. for (var i = 0; i < times.length; ++i)
  112. average += times[i];
  113. average /= times.length;
  114. if (average < 0)
  115. average = 0;
  116.  
  117. // Truncate the result to 2 decimals, or more for more iterations.
  118. var decimals = (precise ? 2 : 0);
  119. for (var order = 2; order <= iterations; order *= 10)
  120. ++decimals;
  121. var str = average.toFixed(decimals);
  122.  
  123. if (userGiven)
  124. str = Locale.$STRF("commandline.TimeUsageAverage", [str, iterations]);
  125. else
  126. str = Locale.$STRF("commandline.TimeUsage", [str]);
  127. Firebug.Console.logFormatted([str], context, "log");
  128. };
Add Comment
Please, Sign In to add comment