UNPKG

processing-js

Version:

For the project website, visit http://processingjs.org

383 lines (333 loc) • 13.7 kB
<!doctype html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>Processing.js Performance Tests</title> <script type="text/javascript" src="https://www.google.com/jsapi"></script> <script> google.load('visualization', '1', {'packages':['corechart']}); </script> <script src="../../processing.js"></script> <script src="tests.js"></script> <style> .test { border: solid 1px; margin: 5px; } .title { margin-left: 5px; } </style> </head> <body> <h1>Processing.js Performance Test Runner</h1> <p>To start the tests click Start. Each test is run in order (downloaded from the server). Tests are run for a maximum number of frames (specified below), and the time recorded.</p> <p>Reference tests can be run from <a href="/ref" target="_blank">here.</a> <h3>Settings</h3> <div>Run Tests: <select id="test-type" onchange="updateSelectedTests();"> <option value="2D,3D" selected="selected">2D and 3D</option> <option value="2D">2D Only</option> <option value="3D">3D Only</option> <option value="Blend">Blend Only</option> <option value="PImage">PImage Only</option> <option value="PVector">PVector Only</option> <option value="Crisp">Crisp</option> <option value="Calibration">Calibration</option> </select>&nbsp; Iterations Per Test: <input type="text" size="4" id="iterations" onchange="updateIterations();">&nbsp; <input onclick="runTests(selectedTests);" type="button" value="Start"></input><span id="testCount"></span></div> <h3>Results [total time for <span id="curTest">0</span> tests: <span id="totalTime">0</span>ms] <button id="report" style="display:none" onclick="report();">Generate Report</button></h3> <div id="status" style="margin-bottom: 10px; display: none;">Running... (this may take some time)</div> <div id="results-chart"></div> <div id="results" style="margin: 5px; padding-top: 10px;"></div> <div id="total"></div> <script> var MAX_TEST_TIME = 5000; // ms of time to allow a test to run before halting and failing. var selectedTests = []; var finishedTests; var failedTests = 0; var totalTime = 0; var total = document.getElementById('total'); total.innerHTML = ''; updateSelectedTests(); // Tolerance values and kernel for blur var iterationCount = 1000; document.getElementById('iterations').value = iterationCount; function generateReport(tests) { var report = { testDate: Date.now(), userAgent: window.navigator.userAgent, data: [] }; for (var i=0; i < tests.length; i++) { if (tests[i].completed) { report.data.push(tests[i]); } } return JSON.stringify(report); } function report() { if (!finishedTests) { alert("You must run the tests first."); return; } // Using text/plain vs. application/json so it's easier to copy/paste document.location.href = "data:text/plain," + generateReport(finishedTests); } /** * Set up the test run filters */ function updateSelectedTests() { var selectControl = document.getElementById('test-type'); var selectedTags = selectControl.value.split(','); selectedTests = new Array(); for (var i = 0; i < tests.length; ++i) { var found = false; // checking if any selected tags present in test tags for (var j = 0; j < selectedTags.length && !found; ++j) { for (var q = 0; q < tests[i].tags.length && !found; ++q) { if (tests[i].tags[q] == selectedTags[j]) found = true; } } if (found) { selectedTests.push(tests[i]); } } var testCount = document.getElementById('testCount'); testCount.innerHTML = '&nbsp;(' + selectedTests.length + ' tests)'; } /** * Change how many times each perf test runs before reporting */ function updateIterations() { var newIterationCount = document.getElementById('iterations').value; if (newIterationCount) { iterationCount = parseInt(newIterationCount, 10); } } /** * get a file with cache breaking t=... */ function download(file) { var req = new XMLHttpRequest(); req.open('GET', file + "?t=" + Date.now(), false); if (req.overrideMimeType) { req.overrideMimeType('text/plain'); } req.send(null); if (req.status != 200 && req.status !=0) { return null; } else { return req.responseText; } } /** * get a test's source code */ function getTest(testName) { var responseText = download(testName); function is3D(script) { // look for size(100,100,OPENGL) or size(100,100,P3D) var match = script.match(/size\([\s]*[\d]+[\s]*\,[\s]*[\d]+[\s]*\,?([^\)]+)?\)/); if (match && match[1]) { return match[1] == "OPENGL" || match[1] == "P3D"; } return false; } if (!responseText) { return null; } // Split out the canvas info in the comment: var test = {name: testName, code: responseText}; test.is3D = is3D(test.code); return test; } /** * Generate the performance chart after running all tests */ function drawResultsChart() { var dataTable = new google.visualization.DataTable(); dataTable.addColumn('string', 'Test'); dataTable.addColumn('number', 'Time per Frame (ms)'); var test, i; for (i=0; i<tests.length; i++) { test = tests[i]; dataTable.addRow([test.path, test.time / (test.iterationOverride || iterationCount)]); } var chart = new google.visualization.BarChart(document.getElementById('results-chart')); chart.draw(dataTable, { title: 'Performance Test Results', width: 800, height: 600, legend: 'none', vAxis: {title: 'Test', textPosition: 'none'}, hAxis: {title: 'Time per Frame (ms)'} }); } /** * Run all performance tests */ function runTests(tests) { var results = document.getElementById('results'); results.innerHTML = ''; var total = document.getElementById('total'); total.innerHTML = ''; var chart = document.getElementById('results-chart'); chart.innerHTML = ''; document.getElementById('report').style.display = "none"; finishedTests = null; failedTests = 0; totalTime = 0; var buildCanvas = function(id, w, h) { var c = document.createElement('canvas'); c.id = id; c.width = w; c.height = h; c.className = "test"; return c; }; var link = function(name) { return '<a href="' + name + '">' + name + '</a>'; }; var titleText = function(testNumber, testTotal, time, testName, testIterations, failMessage) { return "Test (" + testNumber + "/" + testTotal + ") " + link(testName) + (failMessage ? " -- FAILED (" + failMessage + ")" : " -- Total Time for " + testIterations + " frames: <b>" + time + "ms</b>"); }; var tl = tests.length; var lastTest = 0; function nextTest(testNum) { if (testNum < tl) { window.setTimeout(function() { runOne(testNum); }, 50); } else { var passed = tl - failedTests; var info = "Completed " + passed + " of " + tl + " tests (" + failedTests + " failed)."; document.getElementById('status').innerHTML = info; total.innerHTML = info; finishedTests = tests; document.getElementById('status').style.display = "none"; document.getElementById('report').style.display = "inline"; // sort the tests into failed and passed var sortedDivs = []; while (results.hasChildNodes()) { sortedDivs.push(results.firstChild); results.removeChild(results.firstChild); } var failedDiv = document.createElement('div'); failedDiv.innerHTML = '<hr><h3>Failed ' + failedTests + ' of ' + (passed + failedTests) + '</h3>'; results.appendChild(failedDiv); var passDiv = document.createElement('div'); passDiv.innerHTML = '<hr><h3>Passed ' + passed + ' of ' + (passed + failedTests) + '</h3>'; results.appendChild(passDiv); for (var i = 0; i < sortedDivs.length; i++) { if (sortedDivs[i].className === 'failed') { failedDiv.appendChild(sortedDivs[i]); } else { passDiv.appendChild(sortedDivs[i]); } } if (failedDiv.childNodes.length === 0) { var temp = document.createElement('p'); temp.innerHTML = 'No failed tests'; failedDiv.appendChild(temp); } drawResultsChart(); } } function runOne(i) { if (!tests[i]) { alert("Error: no test found."); return; } var test = getTest(tests[i].path); var iterCount = tests[i].iterationOverride || iterationCount; var result = document.createElement('div'); result.id = test.name; var title = document.createElement('div'); title.className = "title"; result.appendChild(title); results.appendChild(result); if (test) { var canvas = buildCanvas(test.name + '-canvas', test.width, test.height); result.appendChild(canvas); // draw the current version from code, timing it var p; try { // Force the test to not loop--we'll do that. var code = "noLoop();\n" + test.code; p = new Processing(canvas, code); function runBenchmark() { try { var startTime = Date.now(), failed = false; for (var iters = 0; iters < iterCount; iters++) { if ( Date.now() - startTime > MAX_TEST_TIME ) { // Exceeded allowable test run time, fail and bail failed = true; failedTests++; break; } p.redraw(); } var endTime = Date.now(); var diff = endTime - startTime; totalTime += diff; if (failed) { result.className = "failed"; title.innerHTML = titleText(i+1, tl, "-", test.name, iterCount, "Test exceeded maximum test time (" + MAX_TEST_TIME + "ms), halted."); } else { result.className = "passed"; title.innerHTML = titleText(i+1, tl, diff, test.name, iterCount); } document.getElementById('totalTime').innerHTML = totalTime; document.getElementById('curTest').innerHTML = (i+1); // Mark this test run a success with time tests[i].completed = true; tests[i].time = diff; } catch (e) { result.className = "failed"; title.innerHTML = titleText(i+1, tl, 0, test.name, iterCount, "Processing failed during execution: " + e.toString()); nextTest(i+1); } var is3D = p.use3DContext; } nextTest(i+1); if (!p.draw) { // preload present var initInterval, attempts = 20; initInterval = setInterval(function() { if (p.draw) { clearInterval(initInterval); runBenchmark(); return; } if (--attempts <= 0) { clearInterval(initInterval); result.className = "failed"; title.innerHTML = titleText(i+1, tl, 0, test.name, iterCount, "Processing failed initialization"); nextTest(i+1); return; } }, 100); return; } runBenchmark(); p.exit(); p = null; } catch (e) { result.className = "failed"; title.innerHTML = titleText(i+1, tl, 0, test.name, iterCount, "Processing failed: " + e.toString()); nextTest(i+1); } } }; window.setTimeout(function() { runOne(0); }, 25); }; </script> <!-- autorun --> <script> document.addEventListener("DOMContentLoaded", function() { var loc = window.location.toString(); if(loc.indexOf("autorun=true") !== -1) { runTests(selectedTests); } }, false); </script> </body> </html>