Created
September 8, 2009 09:43
-
-
Save tjcrowder/182817 to your computer and use it in GitHub Desktop.
Basic performance test page for http://github.com/tjcrowder/prototype/commit/79d3e1dfd32220299f0a5aceacfc6fd3ffa2a089
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | |
<html> | |
<head> | |
<meta http-equiv="Content-type" content="text/html;charset=UTF-8"> | |
<title>New Supercalls Performance Test Page</title> | |
<style type='text/css'> | |
#log p { | |
margin: 0; | |
padding: 0; | |
} | |
.good { | |
color: green; | |
} | |
.bad { | |
color: red; | |
} | |
</style> | |
<script type='text/javascript' src='prototype.js'></script> | |
<script type='text/javascript'> | |
// **** Versions using the old mechanism | |
var OldParent = Class.create((function(){ | |
function nifty(arg1) { | |
return "OP(" + arg1 + ")"; | |
} | |
return {nifty: nifty}; | |
})()); | |
var OldChild = Class.create(OldParent, (function(){ | |
function nifty($super, arg1) { | |
return $super(arg1) + " < OC"; | |
} | |
return {nifty: nifty}; | |
})()); | |
var OldGrandChild = Class.create(OldChild, (function(){ | |
function nifty($super, arg1) { | |
return $super(arg1) + " < OGC"; | |
} | |
return {nifty: nifty}; | |
})()); | |
// **** Versions using the new mechanism | |
var NewParent = Class.create((function() { | |
function nifty(arg1) { | |
return "NP(" + arg1 + ")"; | |
} | |
return {nifty: nifty}; | |
})()); | |
var NewChild = Class.create(NewParent, (function() { | |
function nifty(arg1) { | |
return nifty.$super.call(this, arg1) + " < NC"; | |
//Use this to see how slow arguments.callee is! | |
// return arguments.callee.$super.call(this, arg1) + " < NC"; | |
} | |
return {nifty: nifty}; | |
})()); | |
var NewGrandChild = Class.create(NewChild, (function() { | |
function nifty(arg1) { | |
return nifty.$super.call(this, arg1) + " < NGC"; | |
//Use this to see how slow arguments.callee is! | |
// return arguments.callee.$super.call(this, arg1) + " < NGC"; | |
} | |
return {nifty: nifty}; | |
})()); | |
document.observe("dom:loaded", function() { | |
$('btnClearLog').observe('click', clearLog); | |
$('btnTestFunctionality').observe('click', function() { | |
runTests({functionality: true}); | |
}); | |
$('btnTestPerformance').observe('click', function() { | |
runTests({performance: true}); | |
}); | |
}); | |
function runTests(tests, stage) { | |
stage = stage || 0; | |
switch (stage) { | |
case 0: | |
$$('input').invoke('disable'); | |
break; | |
case 1: | |
try { | |
testWorker(tests); | |
} | |
catch (e) { | |
write("Exception: " + e, false); | |
} | |
break; | |
case 2: | |
$$('input').invoke('enable'); | |
break; | |
} | |
if (stage < 2) { | |
runTests.delay(0.2, tests, stage + 1); | |
} | |
} | |
function testWorker(tests) { | |
var count, countPerLoop, change, otime, ntime, s, failures, | |
oParent, oChild, oGrandChild, | |
nParent, nChild, nGrandChild; | |
// Get instances | |
oParent = new OldParent(); | |
oChild = new OldChild(); | |
oGrandChild = new OldGrandChild(); | |
nParent = new NewParent(); | |
nChild = new NewChild(); | |
nGrandChild = new NewGrandChild(); | |
// **** Functionality first | |
if (tests.functionality) { | |
failures = 0; | |
// The basics | |
if (!assertEqual(oParent.nifty('hi'), "OP(hi)") ) ++failures; | |
if (!assertEqual(oChild.nifty('hi'), "OP(hi) < OC") ) ++failures; | |
if (!assertEqual(oGrandChild.nifty('hi'), "OP(hi) < OC < OGC")) ++failures; | |
if (!assertEqual(nParent.nifty('hi'), "NP(hi)") ) ++failures; | |
if (!assertEqual(nChild.nifty('hi'), "NP(hi) < NC") ) ++failures; | |
if (!assertEqual(nGrandChild.nifty('hi'), "NP(hi) < NC < NGC")) ++failures; | |
// Replacing a method | |
OldChild.addMethods((function(){ | |
function nifty($super, arg1) { | |
return $super(arg1) + " < OC!"; | |
} | |
return {nifty: nifty}; | |
})()); | |
NewChild.addMethods((function(){ | |
function nifty(arg1) { | |
return nifty.$super.call(this, arg1) + " < NC!"; | |
} | |
return {nifty: nifty}; | |
})()); | |
if (!assertEqual(oGrandChild.nifty('hi'), "OP(hi) < OC! < OGC")) ++failures; | |
if (!assertEqual(nGrandChild.nifty('hi'), "NP(hi) < NC! < NGC")) ++failures; | |
if (failures > 0) { | |
write("Functionality tests failures: " + failures, false); | |
} | |
else { | |
write("All functionality tests passed", true); | |
} | |
write("<hr>"); | |
} | |
// **** Performance | |
if (tests.performance) { | |
// Warm up | |
test(oGrandChild, 100); | |
test(nGrandChild, 100); | |
// Four tests interwoven to even out environment concerns | |
count = $F('txtCount'); | |
if (isNaN(count) || count < 0) { | |
count = 2000; | |
$('txtCount').setValue(count); | |
} | |
countPerLoop = Math.round(count / 4); | |
otime = ntime = 0; | |
for (n = 4; n > 0; --n) { | |
otime += test(oGrandChild, countPerLoop); | |
ntime += test(nGrandChild, countPerLoop); | |
} | |
write("test loops: " + count); | |
write("Old mechanism time: " + otime + "ms", otime <= ntime); | |
write("New mechanism time: " + ntime + "ms", ntime <= otime); | |
if (otime + ntime < 15000) { | |
write("*** The test was a bit short, the timing data may be suspect; try more loops."); | |
} | |
change = (ntime - otime) / otime; | |
write("Improvement: " + round(-change * 100, 2) + "%, e.g., old takes " + round(otime / ntime, 2) + " times as long as new."); | |
write("<hr>"); | |
} | |
} | |
function now() { | |
return new Date().getTime(); | |
} | |
function round(value, places) { | |
var tenx; | |
tenx = Math.pow(10, places); | |
return Math.round(value * tenx) / tenx; | |
} | |
function test(obj, count) { | |
var s, start, n; | |
s = ""; | |
start = now(); | |
for (n = count; n > 0; --n) | |
{ | |
s += obj.nifty('hi'); | |
} | |
return now() - start; | |
} | |
function assertEqual(a, b) { | |
var flag; | |
if (a == b) { | |
flag = true; | |
write("GOOD: " + a.escapeHTML(), flag); | |
} | |
else { | |
flag = false; | |
write("Expected '" + b.escapeHTML() + "', got '" + a.escapeHTML() + "'", flag); | |
} | |
return flag; | |
} | |
function write(msg, flag) { | |
var opentag; | |
if (typeof flag != 'undefined') { | |
opentag = "<p class='" + (flag ? "good" : "bad") + "'>"; | |
} | |
else { | |
opentag = "<p>"; | |
} | |
$('log').innerHTML += opentag + msg + "</" + "p>"; | |
return flag; | |
} | |
function clearLog() { | |
$('log').innerHTML = ""; | |
} | |
</script> | |
</head> | |
<body><div> | |
<input type='button' id='btnClearLog' value='Clear Log'> | |
<input type='button' id='btnTestFunctionality' value='Test Functionality'> | |
<input type='button' id='btnTestPerformance' value='Test Performance'> | |
Test loops: <input type='text' id='txtCount' value='5000'> | |
(suggest about 5,000 for IE, 200,000 for Chrome, 100,000 for Firefox or Safari) | |
<hr> | |
<div id='log'></div> | |
</div></body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment