Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2150 mathias 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
          {
179
            name: "builderForEach",
180
            test: function() {
181
              var b = new dojox.string.Builder();
182
              dojo.forEach(words, function(w) {
183
                b.append(w);
184
              });
185
              return b.toString();
186
            }
187
          },
188
          */
189
          {
190
            name: "builderReusedFor",
191
            test: function() {
192
              _builder.clear();
193
              for(var i = 0; i < words.length; i++) {
194
                _builder.append(words[i]);
195
              }
196
              return _builder.toString();
197
            }
198
          },
199
          {
200
            name: "builderOnce",
201
            test: function() {
202
              var b = new dojox.string.Builder();
203
              b.appendArray(words);
204
              return b.toString();
205
            }
206
          },
207
          {
208
            name: "builderReusedOnce",
209
            test: function() {
210
              _builder.clear();
211
              _builder.appendArray(words);
212
              return _builder.toString();
213
            }
214
          },
215
          {
216
            name: "plusFor",
217
            test: function() {
218
              var s = "";
219
              for(var i = 0; i < words.length; i++) {
220
                s += words[i];
221
              }
222
              return s;
223
            }
224
          },
225
          /*
226
          {
227
            name: "plusForAlias",
228
            test: function() {
229
              var s = "", w = words, l = w.length;
230
              for(var i = 0; i < l; i++) {
231
                s += w[i];
232
              }
233
              return s;
234
            }
235
          },
236
          {
237
            name: "plusForEach",
238
            test: function() {
239
              var s = "";
240
              dojo.forEach(words, function(w) { s += w; });
241
              return s;
242
            }
243
          },*/
244
          {
245
            name: "joinOnce",
246
            test: function() {
247
              return words.join("");
248
            }
249
          },
250
          {
251
            name: "joinFor",
252
            test: function() {
253
              var a = [];
254
              for(var i = 0; i < words.length; i++) {
255
                a.push(words[i]);
256
              }
257
              return a.join("");
258
            }
259
          }/*,
260
          {
261
            name: "joinForAlias",
262
            test: function() {
263
              var a = [], w = words, l = w.length;
264
              for(var i = 0; i <l; i++) {
265
                a.push(w[i]);
266
              }
267
              return a.join("");
268
            }
269
          },
270
          {
271
            name: "joinForEach",
272
            test: function() {
273
              var a = [];
274
              dojo.forEach(words, function(w) { a.push(w); });
275
              return a.join("");
276
            }
277
          }
278
          */
279
        ],
280
        words: words,
281
        expected: expected,
282
        overhead: function() {
283
          var w = words;
284
          var l = w.length;
285
          for(var i=0; i < l; i++) {
286
            ident(w[i]);
287
          }
288
        }
289
      };
290
    }
291
 
292
    function buildAndRunSet(words, dict, times) {
293
      runSet(buildTestSet(words, dict), times);
294
    }
295
 
296
    function runSuite() {
297
      var suite = [
298
        {
299
          words: 2,
300
          times: 10000
301
        },
302
        {
303
          words: 4,
304
          times: 10000
305
        },
306
        {
307
          words: 8,
308
          times: 10000
309
        },
310
        {
311
          words: 16,
312
          times: 10000
313
        },
314
        {
315
          words: 32,
316
          times: 10000
317
        },
318
        {
319
          words: 64,
320
          times: 10000
321
        },
322
        {
323
          words: 128,
324
          times: 1000
325
        },
326
        {
327
          words: 256,
328
          times: 1000
329
        },
330
        {
331
          words: 512,
332
          times: 1000
333
        },
334
        {
335
          words: 1024,
336
          times: 1000
337
        },
338
        {
339
          words: 2048,
340
          times: 1000
341
        },
342
        {
343
          words: 4096,
344
          times: 100
345
        },
346
        {
347
          words: 8192,
348
          times: 100
349
        }
350
      ];
351
 
352
      var totalSuite = dojo.map(suite, function(s) { var n = {}; dojo.mixin(n,s); n.dict = lipsum; return n; });
353
      totalSuite = totalSuite.concat(dojo.map(suite, function(s) { var n = {}; dojo.mixin(n,s); n.dict = lipsumLong; return n; }));
354
      console.log(totalSuite);
355
 
356
      var handle = dojo.subscribe("perf/run/done", _run);
357
      dojo.subscribe("perf/run/done", function(){ console.log("perf run done"); });
358
 
359
      function _run() {
360
        var t = totalSuite.shift();
361
        if(t) buildAndRunSet(t.words, t.dict, t.times);
362
        if(totalSuite.length == 0) dojo.unsubscribe(handle);
363
      }
364
 
365
      _run();
366
    }
367
 
368
    function ident(i) { return i; }
369
    </script>
370
    <style type="text/css">
371
    html {
372
      font-family: Lucida Grande, Tahoma;
373
    }
374
    div { margin-bottom: 1em; }
375
    #results {
376
      border: 1px solid #999;
377
      border-collapse: collapse;
378
    }
379
    #results caption {
380
      font-size: medium;
381
      font-weight: bold;
382
    }
383
    #results td, #results th {
384
      text-align: right;
385
      width: 10em;
386
      font-size: small;
387
      white-space: nowrap;
388
    }
389
    #wordsCol { background: yellow; }
390
    td.max { color: red; font-weight: bold; }
391
    td.min { color: green; font-weight: bold; }
392
    </style>
393
  </head>
394
  <body>
395
    <table>
396
      <tr><td><label for="numWords">Words</label></td><td><input type="text" id="numWords" value="100"/></td></tr>
397
      <tr><td><label for="numIters">Iterations</label></td><td><input type="text" id="numIters" value="1000"/></td></tr>
398
      <tr><td><label for="dict">Dictionary</label></td><td><input type="text" id="dict" value="lipsum"></td></tr>
399
      <tr><td></td><td><button id="run" disabled>Run Tests!</button></td></tr>
400
    </table>
401
    <div id="mess"></div>
402
  </body>
403
</html>