source: Dev/branches/rest-dojo-ui/client/dojox/string/tests/BuilderPerf.html @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 11.3 KB
Line 
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
2  "http://www.w3.org/TR/html4/strict.dtd">
3<html>
4  <head>
5    <title>Builder Perf Tests</title>
6    <script type="text/javascript" src="../../../dojo/dojo.js"></script>
7    <script type="text/javascript" src="../Builder.js"></script>
8    <script type="text/javascript" src="lipsum.js"></script>
9    <script type="text/javascript">
10
11    dojo.addOnLoad(function(){
12      dojo.byId("run").disabled="";
13      dojo.connect(dojo.byId("run"),
14                   "onclick",
15                   function(evt) {
16                     setTimeout(function() {
17                       var words = parseInt(dojo.byId("numWords").value) || 10;
18                       var iters = parseInt(dojo.byId("numIters").value) || 1000;
19                       var dict = eval(dojo.byId("dict").value);
20                       buildAndRunSet(words, dict, iters);
21                      }, 0);
22                    });
23    });
24   
25    function element(tag, textOrChildOrArray) {
26      var e = document.createElement(tag);
27      function append(n) {
28        if(dojo.isString(n)){
29          n = document.createTextNode(n);
30        }
31        e.appendChild(n);
32      }
33      if(dojo.isArray(textOrChildOrArray)) {
34        dojo.forEach(textOrChildOrArray, append);
35      }else{
36        append(textOrChildOrArray);
37      }
38      return e;
39    }
40   
41    function log(t) {
42      dojo.byId("mess").innerHTML = t;
43      console.log(t);
44    }
45   
46    function reportRun(results){
47      var runs = results.runs
48      var report = element("dl",
49                     element("dt",
50                             "Run with " + results.words + " words, " +
51                                           results.iterations + " iterations, for loop overhead of " +
52                                           results.overhead + ", average phrase of " +
53                                           results.wordSize + " characters"));
54                         
55      runs.sort(function(a,b) { return a.time - b.time; });
56      dojo.forEach(runs, function(r) {
57        report.appendChild(element("dd", r.time + " - " + r.name));
58      });
59     
60      dojo.body().appendChild(report);
61    }
62   
63    function runTest(test, iterations, expected) {
64      var i;
65      if(expected != test()) throw new Error("Test failed expecting " + expected + ", got " + test());
66      var start = new Date().getTime(), end;
67      for(i=0; i < iterations; i++){
68        test();
69      }
70      end = new Date().getTime();
71      return end-start;
72    }
73   
74    function runSet(set, iterations){
75     
76      function averagePhraseLen(words) {
77        var sizes = dojo.map(words, function(w) { return w.length; });
78        var total = 0;
79        dojo.forEach(sizes, function(s) { total += s; });
80        return total / sizes.length;
81      }
82     
83      var tests = set.tests.concat(); //copy tests
84      var resultSet = {};
85      resultSet.words = set.words.length;
86      resultSet.overhead = runTest(set.overhead, iterations);
87      resultSet.iterations = iterations;
88      resultSet.wordSize = averagePhraseLen(set.words);
89      var runs = [];
90     
91      function _run() {
92        var t = tests.pop();
93        try {
94          log("Running " + t.name);
95          if(t) runs.push({ name: t.name, time: runTest(t.test, iterations, set.expected)});
96        } catch(e) {
97          console.error("Error running " + t.name);
98          console.error(e);
99        }
100        if(tests.length > 0) {
101          setTimeout(_run, 0);
102        }
103        else {
104          log("Done!");
105          resultSet.runs = runs;
106          reportRun(resultSet);
107          dojo.publish("perf/run/done");
108        }
109      }
110      setTimeout(_run, 25);
111    }
112   
113    function buildTestSet(numWords, dict) {
114      var words = [], i, dl = dict.length;
115      for(i = numWords; i > 0; i-=dl) {
116        if(i >= dl) { words = words.concat(dict); }
117        else { words = words.concat(dict.slice(-i)); }
118      }
119      if(words.length != numWords) throw new Error("wrong number of words, got " + words.length + ", expected " + numWords);
120     
121      var expected = words.join("");
122     
123      var _builder = new dojox.string.Builder();
124     
125      return {
126        tests: [
127          {
128            name: "concatFor",
129            test: function() {
130              var s = "";
131              for(var i = 0; i < words.length; i++) {
132                s = s.concat(words[i]);
133              }
134              return s;
135            }
136          },
137          /*
138          {
139            name: "concatForAlias",
140            test: function() {
141              var s = "", w = words, l = w.length;
142              for(var i = 0; i < l; i++) {
143                s = s.concat(w[i]);
144              }
145              return s;
146            }
147          },
148          {
149            name: "concatForEach",
150            test: function() {
151              var s = "";
152              dojo.forEach(words, function(w) {
153                s = s.concat(w);
154              });
155              return s;
156            }
157          },
158          */
159          {
160            name: "concatOnce",
161            test: function() {
162              var s = "";
163              s = String.prototype.concat.apply(s, words);
164              return s;
165            }
166          },
167          {
168            name: "builderFor",
169            test: function() {
170              var b = new dojox.string.Builder();
171              for(var i = 0; i < words.length; i++) {
172                b.append(words[i]);
173              }
174              return b.toString();
175            }
176          },
177          {
178            name: "builderForMulti",
179            test: function() {
180              var b = new dojox.string.Builder();
181              for(var i = 0; i < words.length; i+=2) {
182                                  b.append(words[i], words[i+1]);
183              }
184              return b.toString();
185            }
186          },
187          /*
188          {
189            name: "builderForEach",
190            test: function() {
191              var b = new dojox.string.Builder();
192              dojo.forEach(words, function(w) {
193                b.append(w);
194              });
195              return b.toString();
196            }
197          },
198          */
199          {
200            name: "builderReusedFor",
201            test: function() {
202              _builder.clear();
203              for(var i = 0; i < words.length; i++) {
204                _builder.append(words[i]);
205              }
206              return _builder.toString();
207            }
208          },
209          {
210            name: "builderOnce",
211            test: function() {
212              var b = new dojox.string.Builder();
213              b.appendArray(words);
214              return b.toString();
215            }
216          },
217          {
218            name: "builderReusedOnce",
219            test: function() {
220              _builder.clear();
221              _builder.appendArray(words);
222              return _builder.toString();
223            }
224          },
225          {
226            name: "plusFor",
227            test: function() {
228              var s = "";
229              for(var i = 0; i < words.length; i++) {
230                s += words[i];
231              }
232              return s;
233            }
234          },
235          /*
236          {
237            name: "plusForAlias",
238            test: function() {
239              var s = "", w = words, l = w.length;
240              for(var i = 0; i < l; i++) {
241                s += w[i];
242              }
243              return s;
244            }
245          },
246          {
247            name: "plusForEach",
248            test: function() {
249              var s = "";
250              dojo.forEach(words, function(w) { s += w; });
251              return s;
252            }
253          },*/
254          {
255            name: "joinOnce",
256            test: function() {
257              return words.join("");
258            }
259          },
260          {
261            name: "joinFor",
262            test: function() {
263              var a = [];
264              for(var i = 0; i < words.length; i++) {
265                a.push(words[i]);
266              }
267              return a.join("");
268            }
269          }/*,
270          {
271            name: "joinForAlias",
272            test: function() {
273              var a = [], w = words, l = w.length;
274              for(var i = 0; i <l; i++) {
275                a.push(w[i]);
276              }
277              return a.join("");
278            }
279          },
280          {
281            name: "joinForEach",
282            test: function() {
283              var a = [];
284              dojo.forEach(words, function(w) { a.push(w); });
285              return a.join("");
286            }
287          }
288          */
289        ],
290        words: words,
291        expected: expected,
292        overhead: function() {
293          var w = words;
294          var l = w.length;
295          for(var i=0; i < l; i++) {
296            ident(w[i]);
297          }
298        }
299      };
300    }
301   
302    function buildAndRunSet(words, dict, times) {
303      runSet(buildTestSet(words, dict), times);
304    }
305   
306    function runSuite() {
307      var suite = [
308        {
309          words: 2,
310          times: 10000
311        },
312        {
313          words: 4,
314          times: 10000
315        },
316        {
317          words: 8,
318          times: 10000
319        },
320        {
321          words: 16,
322          times: 10000
323        },
324        {
325          words: 32,
326          times: 10000
327        },
328        {
329          words: 64,
330          times: 10000
331        },
332        {
333          words: 128,
334          times: 1000
335        },
336        {
337          words: 256,
338          times: 1000
339        },
340        {
341          words: 512,
342          times: 1000
343        },
344        {
345          words: 1024,
346          times: 1000
347        },
348        {
349          words: 2048,
350          times: 1000
351        },
352        {
353          words: 4096,
354          times: 100
355        },
356        {
357          words: 8192,
358          times: 100
359        }
360      ];
361     
362      var totalSuite = dojo.map(suite, function(s) { var n = {}; dojo.mixin(n,s); n.dict = lipsum; return n; });
363      totalSuite = totalSuite.concat(dojo.map(suite, function(s) { var n = {}; dojo.mixin(n,s); n.dict = lipsumLong; return n; }));
364      console.log(totalSuite);
365     
366      var handle = dojo.subscribe("perf/run/done", _run);
367      dojo.subscribe("perf/run/done", function(){ console.log("perf run done"); });
368     
369      function _run() {
370        var t = totalSuite.shift();
371        if(t) buildAndRunSet(t.words, t.dict, t.times);
372        if(totalSuite.length == 0) dojo.unsubscribe(handle);
373      }
374     
375      _run();
376    }
377   
378    function ident(i) { return i; }
379    </script>
380    <style type="text/css">
381    html {
382      font-family: Lucida Grande, Tahoma;
383    }
384    div { margin-bottom: 1em; }
385    #results {
386      border: 1px solid #999;
387      border-collapse: collapse;
388    }
389    #results caption {
390      font-size: medium;
391      font-weight: bold;
392    }
393    #results td, #results th {
394      text-align: right;
395      width: 10em;
396      font-size: small;
397      white-space: nowrap;
398    }
399    #wordsCol { background: yellow; }
400    td.max { color: red; font-weight: bold; }
401    td.min { color: green; font-weight: bold; }
402    </style>
403  </head>
404  <body>
405    <table>
406      <tr><td><label for="numWords">Words</label></td><td><input type="text" id="numWords" value="100"/></td></tr>
407      <tr><td><label for="numIters">Iterations</label></td><td><input type="text" id="numIters" value="1000"/></td></tr>
408      <tr><td><label for="dict">Dictionary</label></td><td><input type="text" id="dict" value="lipsum"></td></tr>
409      <tr><td></td><td><button id="run" disabled>Run Tests!</button></td></tr>
410    </table>
411    <div id="mess"></div>   
412  </body>
413</html>
Note: See TracBrowser for help on using the repository browser.