404 lines
11 KiB
HTML
404 lines
11 KiB
HTML
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||
|
"http://www.w3.org/TR/html4/strict.dtd">
|
||
|
<html>
|
||
|
<head>
|
||
|
<title>Builder Perf Tests</title>
|
||
|
<script type="text/javascript" src="../../../dojo/dojo.js"></script>
|
||
|
<script type="text/javascript" src="../Builder.js"></script>
|
||
|
<script type="text/javascript" src="lipsum.js"></script>
|
||
|
<script type="text/javascript">
|
||
|
|
||
|
dojo.addOnLoad(function(){
|
||
|
dojo.byId("run").disabled="";
|
||
|
dojo.connect(dojo.byId("run"),
|
||
|
"onclick",
|
||
|
function(evt) {
|
||
|
setTimeout(function() {
|
||
|
var words = parseInt(dojo.byId("numWords").value) || 10;
|
||
|
var iters = parseInt(dojo.byId("numIters").value) || 1000;
|
||
|
var dict = eval(dojo.byId("dict").value);
|
||
|
buildAndRunSet(words, dict, iters);
|
||
|
}, 0);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
function element(tag, textOrChildOrArray) {
|
||
|
var e = document.createElement(tag);
|
||
|
function append(n) {
|
||
|
if(dojo.isString(n)){
|
||
|
n = document.createTextNode(n);
|
||
|
}
|
||
|
e.appendChild(n);
|
||
|
}
|
||
|
if(dojo.isArray(textOrChildOrArray)) {
|
||
|
dojo.forEach(textOrChildOrArray, append);
|
||
|
}else{
|
||
|
append(textOrChildOrArray);
|
||
|
}
|
||
|
return e;
|
||
|
}
|
||
|
|
||
|
function log(t) {
|
||
|
dojo.byId("mess").innerHTML = t;
|
||
|
console.log(t);
|
||
|
}
|
||
|
|
||
|
function reportRun(results){
|
||
|
var runs = results.runs
|
||
|
var report = element("dl",
|
||
|
element("dt",
|
||
|
"Run with " + results.words + " words, " +
|
||
|
results.iterations + " iterations, for loop overhead of " +
|
||
|
results.overhead + ", average phrase of " +
|
||
|
results.wordSize + " characters"));
|
||
|
|
||
|
runs.sort(function(a,b) { return a.time - b.time; });
|
||
|
dojo.forEach(runs, function(r) {
|
||
|
report.appendChild(element("dd", r.time + " - " + r.name));
|
||
|
});
|
||
|
|
||
|
dojo.body().appendChild(report);
|
||
|
}
|
||
|
|
||
|
function runTest(test, iterations, expected) {
|
||
|
var i;
|
||
|
if(expected != test()) throw new Error("Test failed expecting " + expected + ", got " + test());
|
||
|
var start = new Date().getTime(), end;
|
||
|
for(i=0; i < iterations; i++){
|
||
|
test();
|
||
|
}
|
||
|
end = new Date().getTime();
|
||
|
return end-start;
|
||
|
}
|
||
|
|
||
|
function runSet(set, iterations){
|
||
|
|
||
|
function averagePhraseLen(words) {
|
||
|
var sizes = dojo.map(words, function(w) { return w.length; });
|
||
|
var total = 0;
|
||
|
dojo.forEach(sizes, function(s) { total += s; });
|
||
|
return total / sizes.length;
|
||
|
}
|
||
|
|
||
|
var tests = set.tests.concat(); //copy tests
|
||
|
var resultSet = {};
|
||
|
resultSet.words = set.words.length;
|
||
|
resultSet.overhead = runTest(set.overhead, iterations);
|
||
|
resultSet.iterations = iterations;
|
||
|
resultSet.wordSize = averagePhraseLen(set.words);
|
||
|
var runs = [];
|
||
|
|
||
|
function _run() {
|
||
|
var t = tests.pop();
|
||
|
try {
|
||
|
log("Running " + t.name);
|
||
|
if(t) runs.push({ name: t.name, time: runTest(t.test, iterations, set.expected)});
|
||
|
} catch(e) {
|
||
|
console.error("Error running " + t.name);
|
||
|
console.error(e);
|
||
|
}
|
||
|
if(tests.length > 0) {
|
||
|
setTimeout(_run, 0);
|
||
|
}
|
||
|
else {
|
||
|
log("Done!");
|
||
|
resultSet.runs = runs;
|
||
|
reportRun(resultSet);
|
||
|
dojo.publish("perf/run/done");
|
||
|
}
|
||
|
}
|
||
|
setTimeout(_run, 25);
|
||
|
}
|
||
|
|
||
|
function buildTestSet(numWords, dict) {
|
||
|
var words = [], i, dl = dict.length;
|
||
|
for(i = numWords; i > 0; i-=dl) {
|
||
|
if(i >= dl) { words = words.concat(dict); }
|
||
|
else { words = words.concat(dict.slice(-i)); }
|
||
|
}
|
||
|
if(words.length != numWords) throw new Error("wrong number of words, got " + words.length + ", expected " + numWords);
|
||
|
|
||
|
var expected = words.join("");
|
||
|
|
||
|
var _builder = new dojox.string.Builder();
|
||
|
|
||
|
return {
|
||
|
tests: [
|
||
|
{
|
||
|
name: "concatFor",
|
||
|
test: function() {
|
||
|
var s = "";
|
||
|
for(var i = 0; i < words.length; i++) {
|
||
|
s = s.concat(words[i]);
|
||
|
}
|
||
|
return s;
|
||
|
}
|
||
|
},
|
||
|
/*
|
||
|
{
|
||
|
name: "concatForAlias",
|
||
|
test: function() {
|
||
|
var s = "", w = words, l = w.length;
|
||
|
for(var i = 0; i < l; i++) {
|
||
|
s = s.concat(w[i]);
|
||
|
}
|
||
|
return s;
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
name: "concatForEach",
|
||
|
test: function() {
|
||
|
var s = "";
|
||
|
dojo.forEach(words, function(w) {
|
||
|
s = s.concat(w);
|
||
|
});
|
||
|
return s;
|
||
|
}
|
||
|
},
|
||
|
*/
|
||
|
{
|
||
|
name: "concatOnce",
|
||
|
test: function() {
|
||
|
var s = "";
|
||
|
s = String.prototype.concat.apply(s, words);
|
||
|
return s;
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
name: "builderFor",
|
||
|
test: function() {
|
||
|
var b = new dojox.string.Builder();
|
||
|
for(var i = 0; i < words.length; i++) {
|
||
|
b.append(words[i]);
|
||
|
}
|
||
|
return b.toString();
|
||
|
}
|
||
|
},
|
||
|
/*
|
||
|
{
|
||
|
name: "builderForEach",
|
||
|
test: function() {
|
||
|
var b = new dojox.string.Builder();
|
||
|
dojo.forEach(words, function(w) {
|
||
|
b.append(w);
|
||
|
});
|
||
|
return b.toString();
|
||
|
}
|
||
|
},
|
||
|
*/
|
||
|
{
|
||
|
name: "builderReusedFor",
|
||
|
test: function() {
|
||
|
_builder.clear();
|
||
|
for(var i = 0; i < words.length; i++) {
|
||
|
_builder.append(words[i]);
|
||
|
}
|
||
|
return _builder.toString();
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
name: "builderOnce",
|
||
|
test: function() {
|
||
|
var b = new dojox.string.Builder();
|
||
|
b.appendArray(words);
|
||
|
return b.toString();
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
name: "builderReusedOnce",
|
||
|
test: function() {
|
||
|
_builder.clear();
|
||
|
_builder.appendArray(words);
|
||
|
return _builder.toString();
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
name: "plusFor",
|
||
|
test: function() {
|
||
|
var s = "";
|
||
|
for(var i = 0; i < words.length; i++) {
|
||
|
s += words[i];
|
||
|
}
|
||
|
return s;
|
||
|
}
|
||
|
},
|
||
|
/*
|
||
|
{
|
||
|
name: "plusForAlias",
|
||
|
test: function() {
|
||
|
var s = "", w = words, l = w.length;
|
||
|
for(var i = 0; i < l; i++) {
|
||
|
s += w[i];
|
||
|
}
|
||
|
return s;
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
name: "plusForEach",
|
||
|
test: function() {
|
||
|
var s = "";
|
||
|
dojo.forEach(words, function(w) { s += w; });
|
||
|
return s;
|
||
|
}
|
||
|
},*/
|
||
|
{
|
||
|
name: "joinOnce",
|
||
|
test: function() {
|
||
|
return words.join("");
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
name: "joinFor",
|
||
|
test: function() {
|
||
|
var a = [];
|
||
|
for(var i = 0; i < words.length; i++) {
|
||
|
a.push(words[i]);
|
||
|
}
|
||
|
return a.join("");
|
||
|
}
|
||
|
}/*,
|
||
|
{
|
||
|
name: "joinForAlias",
|
||
|
test: function() {
|
||
|
var a = [], w = words, l = w.length;
|
||
|
for(var i = 0; i <l; i++) {
|
||
|
a.push(w[i]);
|
||
|
}
|
||
|
return a.join("");
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
name: "joinForEach",
|
||
|
test: function() {
|
||
|
var a = [];
|
||
|
dojo.forEach(words, function(w) { a.push(w); });
|
||
|
return a.join("");
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
],
|
||
|
words: words,
|
||
|
expected: expected,
|
||
|
overhead: function() {
|
||
|
var w = words;
|
||
|
var l = w.length;
|
||
|
for(var i=0; i < l; i++) {
|
||
|
ident(w[i]);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function buildAndRunSet(words, dict, times) {
|
||
|
runSet(buildTestSet(words, dict), times);
|
||
|
}
|
||
|
|
||
|
function runSuite() {
|
||
|
var suite = [
|
||
|
{
|
||
|
words: 2,
|
||
|
times: 10000
|
||
|
},
|
||
|
{
|
||
|
words: 4,
|
||
|
times: 10000
|
||
|
},
|
||
|
{
|
||
|
words: 8,
|
||
|
times: 10000
|
||
|
},
|
||
|
{
|
||
|
words: 16,
|
||
|
times: 10000
|
||
|
},
|
||
|
{
|
||
|
words: 32,
|
||
|
times: 10000
|
||
|
},
|
||
|
{
|
||
|
words: 64,
|
||
|
times: 10000
|
||
|
},
|
||
|
{
|
||
|
words: 128,
|
||
|
times: 1000
|
||
|
},
|
||
|
{
|
||
|
words: 256,
|
||
|
times: 1000
|
||
|
},
|
||
|
{
|
||
|
words: 512,
|
||
|
times: 1000
|
||
|
},
|
||
|
{
|
||
|
words: 1024,
|
||
|
times: 1000
|
||
|
},
|
||
|
{
|
||
|
words: 2048,
|
||
|
times: 1000
|
||
|
},
|
||
|
{
|
||
|
words: 4096,
|
||
|
times: 100
|
||
|
},
|
||
|
{
|
||
|
words: 8192,
|
||
|
times: 100
|
||
|
}
|
||
|
];
|
||
|
|
||
|
var totalSuite = dojo.map(suite, function(s) { var n = {}; dojo.mixin(n,s); n.dict = lipsum; return n; });
|
||
|
totalSuite = totalSuite.concat(dojo.map(suite, function(s) { var n = {}; dojo.mixin(n,s); n.dict = lipsumLong; return n; }));
|
||
|
console.log(totalSuite);
|
||
|
|
||
|
var handle = dojo.subscribe("perf/run/done", _run);
|
||
|
dojo.subscribe("perf/run/done", function(){ console.log("perf run done"); });
|
||
|
|
||
|
function _run() {
|
||
|
var t = totalSuite.shift();
|
||
|
if(t) buildAndRunSet(t.words, t.dict, t.times);
|
||
|
if(totalSuite.length == 0) dojo.unsubscribe(handle);
|
||
|
}
|
||
|
|
||
|
_run();
|
||
|
}
|
||
|
|
||
|
function ident(i) { return i; }
|
||
|
</script>
|
||
|
<style type="text/css">
|
||
|
html {
|
||
|
font-family: Lucida Grande, Tahoma;
|
||
|
}
|
||
|
div { margin-bottom: 1em; }
|
||
|
#results {
|
||
|
border: 1px solid #999;
|
||
|
border-collapse: collapse;
|
||
|
}
|
||
|
#results caption {
|
||
|
font-size: medium;
|
||
|
font-weight: bold;
|
||
|
}
|
||
|
#results td, #results th {
|
||
|
text-align: right;
|
||
|
width: 10em;
|
||
|
font-size: small;
|
||
|
white-space: nowrap;
|
||
|
}
|
||
|
#wordsCol { background: yellow; }
|
||
|
td.max { color: red; font-weight: bold; }
|
||
|
td.min { color: green; font-weight: bold; }
|
||
|
</style>
|
||
|
</head>
|
||
|
<body>
|
||
|
<table>
|
||
|
<tr><td><label for="numWords">Words</label></td><td><input type="text" id="numWords" value="100"/></td></tr>
|
||
|
<tr><td><label for="numIters">Iterations</label></td><td><input type="text" id="numIters" value="1000"/></td></tr>
|
||
|
<tr><td><label for="dict">Dictionary</label></td><td><input type="text" id="dict" value="lipsum"></td></tr>
|
||
|
<tr><td></td><td><button id="run" disabled>Run Tests!</button></td></tr>
|
||
|
</table>
|
||
|
<div id="mess"></div>
|
||
|
</body>
|
||
|
</html>
|