| <!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> |