PerfFun.html 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  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>Perf Tests</title>
  6. <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true"></script>
  7. <script type="text/javascript" src="lipsum.js"></script>
  8. <script type="text/javascript">
  9. dojo.addOnLoad(function(){
  10. dojo.byId("run").disabled="";
  11. dojo.connect(dojo.byId("run"),
  12. "onclick",
  13. function(evt) {
  14. setTimeout(function() {
  15. var words = parseInt(dojo.byId("numWords").value) || 10;
  16. var iters = parseInt(dojo.byId("numIters").value) || 1000;
  17. buildAndRunSet(words, iters);
  18. }, 0);
  19. });
  20. });
  21. function element(tag, textOrChild) {
  22. var e = document.createElement(tag);
  23. if(dojo.isArray(textOrChild)) dojo.forEach(textOrChild, function(c) { e.appendChild(c); });
  24. if(dojo.isString(textOrChild)) e.appendChild(document.createTextNode(textOrChild));
  25. else e.appendChild(textOrChild);
  26. return e;
  27. }
  28. function log(t) {
  29. dojo.byId("mess").innerHTML = t;
  30. }
  31. function reportRun(results){
  32. var runs = results.runs
  33. var report = element("dl",
  34. element("dt",
  35. "Run with " + results.words + " words, " +
  36. results.iterations + " iterations and overhead of " +
  37. results.overhead));
  38. runs.sort(function(a,b) { return a.time - b.time; });
  39. dojo.forEach(runs, function(r) {
  40. report.appendChild(element("dd", r.time + " - " + r.name));
  41. });
  42. dojo.body().appendChild(report);
  43. }
  44. function runTest(test, iterations, expected) {
  45. var i;
  46. if(expected != test()) throw new Error("Test failed expecting " + expected + ", got " + test());
  47. var start = new Date().getTime(), end;
  48. for(i=0; i < iterations; i++){
  49. test();
  50. }
  51. end = new Date().getTime();
  52. return end-start;
  53. }
  54. function runSet(set, iterations){
  55. var tests = set.tests.concat(); //copy tests
  56. var resultSet = {};
  57. resultSet.words = set.words.length;
  58. resultSet.overhead = runTest(function(){}, iterations);
  59. resultSet.iterations = iterations;
  60. var runs = [];
  61. function _run() {
  62. var t = tests.pop();
  63. try {
  64. log("Running " + t.name);
  65. if(t) runs.push({ name: t.name, time: runTest(t.test, iterations, set.expected)});
  66. } catch(e) {
  67. console.error("Error running " + t.name);
  68. console.error(e);
  69. }
  70. if(tests.length > 0) {
  71. setTimeout(_run, 0);
  72. }
  73. else {
  74. log("Done!");
  75. resultSet.runs = runs;
  76. reportRun(resultSet);
  77. }
  78. }
  79. setTimeout(_run, 0);
  80. }
  81. function buildTestSet(numWords) {
  82. var words = [], i, wordsInLipsum = lipsum.length;
  83. for(i = numWords; i > 0; i-=wordsInLipsum) {
  84. if(i >= wordsInLipsum) { words = words.concat(lipsum); }
  85. else { words = words.concat(lipsum.slice(-i)); }
  86. }
  87. if(words.length != numWords) throw new Error("wrong number of words, got " + words.length + ", expected " + numWords);
  88. var expected = words.join("");
  89. //console.log(words);
  90. return {
  91. tests: [
  92. {
  93. name: "dojoForEach",
  94. test: function() {
  95. var s = "";
  96. dojo.forEach(words, function(w) { s+=w; });
  97. return s;
  98. }
  99. },
  100. {
  101. name: "nativeForEach",
  102. test: function() {
  103. var s = "";
  104. words.forEach(function(w) { s += w; });
  105. return s;
  106. }
  107. },
  108. {
  109. name: "forLoop",
  110. test: function() {
  111. var s="",w=words; l=w.length;
  112. for(var i = 0; i < l; i++) {
  113. s += w[i];
  114. }
  115. return s;
  116. }
  117. },
  118. {
  119. name: "forLoopCallingInlineFunction",
  120. test: function() {
  121. var s="",w=words; l=w.length;
  122. function fn(w) { s += w; };
  123. for(var i = 0; i < l; i++) {
  124. fn(w[i]);
  125. }
  126. return s;
  127. }
  128. },
  129. {
  130. name: "forLoopCallingExternalFunction",
  131. test: function() {
  132. g_s="",w=words; l=w.length;
  133. for(var i = 0; i < l; i++) {
  134. externalAppend(w[i]);
  135. }
  136. return g_s;
  137. }
  138. },
  139. {
  140. name: "forLoopWithInCheck",
  141. test: function() {
  142. var s="",w=words; l=w.length;
  143. for(var i = 0; i < l; i++) {
  144. if(i in w) s += w[i];
  145. }
  146. return s;
  147. }
  148. },
  149. {
  150. name: "emptyFor",
  151. test: function() {
  152. var w = words; l = w.length;
  153. for(var i = 0; i < l; i++) empty(w[i]);
  154. return expected;
  155. }
  156. },
  157. {
  158. name: "emptyForEach",
  159. test: function() {
  160. dojo.forEach(words, empty);
  161. return expected;
  162. }
  163. } ,
  164. {
  165. name: "identFor",
  166. test: function() {
  167. var w = words; l = w.length;
  168. for(var i = 0; i < l; i++) ident(w[i]);
  169. return expected;
  170. }
  171. },
  172. {
  173. name: "identForEach",
  174. test: function() {
  175. dojo.forEach(words, ident);
  176. return expected;
  177. }
  178. },
  179. {
  180. name: "addUsingFor",
  181. test: function() {
  182. var x=0;
  183. for(var i=0;i<1000;i++){x=x+a[i];}
  184. return expected; // fake
  185. }
  186. },
  187. {
  188. name: "addUsingForEach",
  189. test: function() {
  190. var x=0;
  191. dojo.forEach(a, function(v,i){x=x+a[i];});
  192. return expected; // fake
  193. }
  194. }
  195. ],
  196. words: words,
  197. expected: expected
  198. };
  199. }
  200. function buildAndRunSet(words, times) {
  201. runSet(buildTestSet(words), times);
  202. }
  203. function ident(w) { return w; }
  204. function empty() { }
  205. var g_s = "";
  206. function externalAppend(w){ g_s += w; }
  207. var a = new Array(1000);
  208. for(var i=0; i<1000;i++){a[i]=i;}
  209. </script>
  210. <style type="text/css">
  211. html {
  212. font-family: Lucida Grande, Tahoma;
  213. }
  214. div { margin-bottom: 1em; }
  215. #results {
  216. border: 1px solid #999;
  217. border-collapse: collapse;
  218. }
  219. #results caption {
  220. font-size: medium;
  221. font-weight: bold;
  222. }
  223. #results td, #results th {
  224. text-align: right;
  225. width: 10em;
  226. font-size: small;
  227. white-space: nowrap;
  228. }
  229. #wordsCol { background: yellow; }
  230. td.max { color: red; font-weight: bold; }
  231. td.min { color: green; font-weight: bold; }
  232. </style>
  233. </head>
  234. <body>
  235. <table>
  236. <tr><td><label for="numWords">Words</label></td><td><input type="text" id="numWords" value="100"/></td></tr>
  237. <tr><td><label for="numIters">Iterations</label></td><td><input type="text" id="numIters" value="1000"/></td></tr>
  238. <tr><td></td><td><button id="run" disabled>Run Tests!</button></td></tr>
  239. </table>
  240. <div id="mess"></div>
  241. </body>
  242. </html>