--- /dev/null
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>Performance Tests</title>
+ <style>
+ body { font-family: Tahoma, Serif; font-size: 9pt; }
+ </style>
+ </head>
+ <body bgcolor="white">
+ <h1>Performance Tests</h1>
+ <input type="button" value="Run Tests" onClick="run();" id="run"/> Filter: <input type="text" size="50" id="filters"/>
+ <div><span id="statusBox"></span> <progress id="progressBox" value="0" style="display:none"></progress></div>
+
+ <div style="padding-top:10px; padding-bottom:10px">
+ <table id="resultTable" border="1" cellspacing="1" cellpadding="4">
+ <thead>
+ <tr>
+ <td>Name</td>
+ <td>Iterations per Run</td>
+ <td>Avg (ms)</td>
+ <td>Min (ms)</td>
+ <td>Max (ms)</td>
+ <td>StdDev (ms)</td>
+ <td>Runs (ms)</td>
+ </tr>
+ </thead>
+ <!-- result rows here -->
+ </table>
+ </div>
+
+ <hr width="80%">
+
+ Result 1: <input type="text" size="100" id="result1"/>
+ <br/>Result 2: <input type="text" size="100" id="result2"/>
+ <br/><input type="button" value="Compare" onClick="compare();" id="compare"/>
+
+ <div style="padding-top:10px; padding-bottom:10px">
+ <table id="compareTable" border="1" cellspacing="1" cellpadding="4">
+ <thead>
+ <tr>
+ <td>Name</td>
+ <td>Result 1 Avg (ms)</td>
+ <td>Result 2 Avg (ms)</td>
+ <td>% Diff</td>
+ </tr>
+ </thead>
+ <!-- result rows here -->
+ </table>
+ </div>
+
+<script type="text/javascript">
+function run() {
+ var runElement = document.getElementById("run");
+ var filtersElement = document.getElementById("filters");
+ var compareElement = document.getElementById("compare");
+ var result1Element = document.getElementById("result1");
+ var result2Element = document.getElementById("result2");
+
+ // Number of runs for each test.
+ var testRuns = 10;
+
+ // Delay between test runs.
+ var runDelay = 0;
+
+ // Retrieve the list of all tests.
+ var allTests = window.GetPerfTests();
+
+ // Populated with the list of tests that will be run.
+ var tests = [];
+ var currentTest = 0;
+
+ var testList = filtersElement.value.trim();
+ if (testList.length > 0) {
+ // Include or exclude specific tests.
+ var included = [];
+ var excluded = [];
+
+ var testNames = testList.split(",");
+
+ // Identify included and excluded tests.
+ for (i = 0; i < testNames.length; ++i) {
+ var testName = testNames[i].trim();
+ if (testName[0] == '-') {
+ // Exclude the test.
+ excluded.push(testName.substr(1));
+ } else {
+ // Include the test.
+ included.push(testName);
+ }
+ }
+
+ if (included.length > 0) {
+ // Only use the included tests.
+ for (i = 0; i < allTests.length; ++i) {
+ var test = allTests[i];
+ var testName = test[0];
+ if (included.indexOf(testName) >= 0)
+ tests.push(test);
+ }
+ } else if (excluded.length > 0) {
+ // Use all tests except the excluded tests.
+ for (i = 0; i < allTests.length; ++i) {
+ var test = allTests[i];
+ var testName = test[0];
+ if (excluded.indexOf(testName) < 0)
+ tests.push(test);
+ }
+ }
+ } else {
+ // Run all tests.
+ tests = allTests;
+ }
+
+ function updateStatusComplete() {
+ var statusBox = document.getElementById("statusBox");
+ statusBox.innerText = 'All tests completed.';
+
+ runElement.disabled = false;
+ filtersElement.disabled = false;
+ result1Element.disabled = false;
+ result2Element.disabled = false;
+ compareElement.disabled = false;
+ }
+
+ function updateStatus(test) {
+ var statusBox = document.getElementById("statusBox");
+ var progressBox = document.getElementById("progressBox");
+
+ if (test.run >= test.totalRuns) {
+ statusBox.innerText = test.name + " completed.";
+ progressBox.style.display = 'none';
+ } else {
+ statusBox.innerText = test.name + " (" + test.run + "/" + test.totalRuns + ")";
+ progressBox.value = (test.run / test.totalRuns);
+ progressBox.style.display = 'inline';
+ }
+ }
+
+ function appendResult(test) {
+ var e = document.getElementById("resultTable");
+
+ // Calculate the average.
+ var avg = test.total / test.totalRuns;
+
+ // Calculate the standard deviation.
+ var sqsum = 0;
+ for (i = 0; i < test.results.length; ++i) {
+ var diff = test.results[i] - avg;
+ sqsum += diff * diff;
+ }
+ var stddev = Math.round(Math.sqrt(sqsum / test.totalRuns) * 100.0) / 100.0;
+
+ e.insertAdjacentHTML("beforeEnd", [
+ "<tr>",
+ "<td>", test.name, "</td>",
+ "<td>", test.iterations, "</td>",
+ "<td>", avg, "</td>",
+ "<td>", test.min, "</td>",
+ "<td>", test.max, "</td>",
+ "<td>", stddev, "</td>",
+ "<td>", test.results.join(", "), "</td>",
+ "<tr>"
+ ].join(""));
+
+ if (result1Element.value.length > 0)
+ result1Element.value += ",";
+ result1Element.value += test.name + "=" + avg;
+ }
+
+ // Execute the test function.
+ function execTestFunc(name) {
+ return window.RunPerfTest(name);
+ }
+
+ // Schedule the next test.
+ function nextTest(test) {
+ appendResult(test);
+ currentTest++;
+ runTest();
+ }
+
+ // Schedule the next step for the current test.
+ function nextTestStep(test) {
+ setTimeout(function () { execTest(test); }, runDelay);
+ }
+
+ // Perform the next step for the current test.
+ function execTest(test) {
+ updateStatus(test);
+
+ if (!test.warmedUp) {
+ execTestFunc(test.name);
+ test.warmedUp = true;
+ return nextTestStep(test);
+ }
+
+ if (test.run >= test.totalRuns)
+ return nextTest(test);
+
+ var elapsed = execTestFunc(test.name);
+ test.results.push(elapsed);
+
+ test.total += elapsed;
+ if (!test.min) test.min = elapsed;
+ else if (test.min > elapsed) test.min = elapsed;
+ if (!test.max) test.max = elapsed;
+ else if (test.max < elapsed) test.max = elapsed;
+
+ test.run++;
+
+ return nextTestStep(test);
+ }
+
+ function runTest() {
+ if (currentTest == tests.length) {
+ updateStatusComplete();
+ return;
+ }
+
+ var test = {
+ name: tests[currentTest][0],
+ iterations: tests[currentTest][1],
+ warmedUp: false,
+ total: 0,
+ totalRuns: testRuns,
+ run: 0,
+ results: []
+ };
+ setTimeout(function () { execTest(test); }, runDelay);
+ }
+
+ // Schedule the first test.
+ if (tests.length > 0) {
+ runElement.disabled = true;
+ filtersElement.disabled = true;
+ result1Element.value = "";
+ result1Element.disabled = true;
+ result2Element.disabled = true;
+ compareElement.disabled = true;
+
+ runTest();
+ }
+}
+
+function compare() {
+ var result1 = document.getElementById("result1").value.trim();
+ var result2 = document.getElementById("result2").value.trim();
+
+ if (result1.length == 0 || result2.length == 0)
+ return;
+
+ var r1values = result1.split(",");
+ var r2values = result2.split(",");
+ for (i = 0; i < r1values.length; ++i) {
+ var r1parts = r1values[i].split("=");
+ var r1name = r1parts[0].trim();
+ var r1val = r1parts[1].trim();
+
+ for (x = 0; x < r2values.length; ++x) {
+ var r2parts = r2values[x].split("=");
+ var r2name = r2parts[0].trim();
+ var r2val = r2parts[1].trim();
+
+ if (r2name == r1name) {
+ appendResult(r1name, r1val, r2val);
+
+ // Remove the matching index.
+ r2values.splice(x, 1);
+ break;
+ }
+ }
+ }
+
+ function appendResult(name, r1val, r2val) {
+ var e = document.getElementById("compareTable");
+
+ // Calculate the percent difference.
+ var diff = Math.round(((r2val - r1val) / r1val) * 10000.0) / 100.0;
+
+ e.insertAdjacentHTML("beforeEnd", [
+ "<tr>",
+ "<td>", name, "</td>",
+ "<td>", r1val, "</td>",
+ "<td>", r2val, "</td>",
+ "<td>", diff, "</td>",
+ "<tr>"
+ ].join(""));
+ }
+}
+</script>
+
+ </body>
+</html>