Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Time execution of a piece of code, with a user-provided number 'iterations'
- * of samples (>= 0), or if 'iterations' is null, just one.
- */
- timeExecution = function(context, code, iterations)
- {
- var userGiven = true;
- if (iterations === null)
- {
- userGiven = false;
- iterations = 1;
- }
- // In FF15 and up, performance.now() provides submillisecond precision;
- // for older versions we will have to fall back to Date.now().
- var precise = ("performance" in window && "now" in window.performance);
- // Build up JavaScript code that evaluates and times 'code'.
- var getTimingCode = function(code)
- {
- var nowF = (precise ? "performance.now()" : "Date.now()");
- var ret = "{ ";
- var timingOverhead = "0";
- if (precise)
- {
- // Warm up timer/JavaScript engine. (This helps a tiny bit, I
- // think. Can't hurt, at least.)
- ret += [nowF, nowF].join("; ") + "; ";
- ret += "document.getElementById('dummy'); ";
- // performance.now() takes some time to run (~0.02ms on my machine);
- // thus, save some consecutive timings so we can account for that.
- // The actual overhead fluctuates, so use the most reasonable value.
- ret += "let __fbt0, __fbt1, __fbt2, __fbt3; ";
- ret += "__fbt0 = " + nowF + "; try {} finally { if (__fbt1 = " + nowF + ") {} } ";
- ret += "__fbt2 = " + nowF + "; try {} finally { if (__fbt3 = " + nowF + ") {} } ";
- timingOverhead = "Math.min(__fbt3 - __fbt2, __fbt1 - __fbt0)";
- }
- ret += "let __fbT0, __fbT1; __fbT0 = " + nowF + "; ";
- // Add a default return value, to avoid printing a random float if
- // the evaluated code lacks statements.
- ret += "void 0; ";
- // Actually evaluate the code.
- ret += "try {\n" + code + "\n} finally {\n";
- // Save the time taken in window.__fbTiming. To retain the last
- // evaluated value for display, wrap the timing calculation/
- // assignment in an expression.
- ret += "if (__fbT1 = " + nowF + ", window.__fbTiming = (__fbT1 - __fbT0) - " + timingOverhead + ") {} ";
- ret += "} }";
- return ret;
- };
- var win = (context.baseWindow ? context.baseWindow : context.window);
- var timeCode = getTimingCode(code);
- var times = [], resArgs;
- for (var i = 0; i < iterations; ++i)
- {
- var save = function() { resArgs = arguments; };
- Firebug.CommandLine.evaluate(timeCode, context, context.thisValue,
- win, save, save);
- // Get the timing out from the global.
- var timing = NaN;
- try
- {
- timing = +win.wrappedJSObject.__fbTiming;
- delete win.wrappedJSObject.__fbTiming;
- }
- catch (e) {}
- times.push(timing);
- // In case of e.g. syntax errors, we have no data to display. Just
- // print the last result/error.
- if (isNaN(timing))
- {
- Firebug.Console.log.apply(Firebug.Console, resArgs);
- return;
- }
- }
- // Print the result of the last iteration.
- Firebug.Console.log.apply(Firebug.Console, resArgs);
- if (precise && ((times.length >= 5 && times[0] < 0.2) ||
- (times.length >= 10 && times[0] < 1.0)))
- {
- // The first ~3 results are slightly too high, on my machine. Throw
- // them away.
- times.splice(0, 3);
- }
- if (times.length >= 10)
- {
- // We have enough data to be able to throw out outliers.
- var edge = Math.floor(times.length * 0.2);
- times.sort(function(a, b) { return a - b; });
- times = times.slice(edge, -edge);
- }
- // Calculate a simple average. If it is negative (from incorrect timing
- // overhead correction - most commonly from timing something empty),
- // show it as 0 instead.
- var average = 0;
- for (var i = 0; i < times.length; ++i)
- average += times[i];
- average /= times.length;
- if (average < 0)
- average = 0;
- // Truncate the result to 2 decimals, or more for more iterations.
- var decimals = (precise ? 2 : 0);
- for (var order = 2; order <= iterations; order *= 10)
- ++decimals;
- var str = average.toFixed(decimals);
- if (userGiven)
- str = Locale.$STRF("commandline.TimeUsageAverage", [str, iterations]);
- else
- str = Locale.$STRF("commandline.TimeUsage", [str]);
- Firebug.Console.logFormatted([str], context, "log");
- };
Add Comment
Please, Sign In to add comment