arrays.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. /*
  2. * Javascript binary array performance tests
  3. * Copyright (C) 2012 Joel Martin
  4. * Licensed under MPL 2.0 (see LICENSE.txt)
  5. */
  6. var ctx, i, j, randlist,
  7. new_normal, new_imageData, new_arrayBuffer,
  8. browser = Browser.browser + " " +
  9. Browser.version + " on " +
  10. Browser.OS,
  11. do_imageData = false,
  12. do_arrayBuffer = false,
  13. conf = {
  14. 'create_cnt' : 2000,
  15. 'read_cnt' : 5000000,
  16. 'write_cnt' : 5000000,
  17. 'iterations' : 0,
  18. 'order_l1' : [browser],
  19. 'order_l2' : ['normal',
  20. 'imageData',
  21. 'arrayBuffer'],
  22. 'order_l3' : ['create',
  23. 'sequentialRead',
  24. 'randomRead',
  25. 'sequentialWrite']
  26. },
  27. stats = {},
  28. testFunc = {},
  29. iteration, arraySize;
  30. var newline = "\n";
  31. if (Util.Engine.trident) {
  32. var newline = "<br>\n";
  33. }
  34. function message(str) {
  35. //console.log(str);
  36. cell = $D('messages');
  37. cell.textContent += str + newline;
  38. cell.scrollTop = cell.scrollHeight;
  39. }
  40. function vmessage(str) {
  41. if (verbose) {
  42. message(str);
  43. } else {
  44. console.log(str);
  45. }
  46. }
  47. new_normal = function() {
  48. var arr = [], i;
  49. for (i = 0; i < arraySize; i++) {
  50. arr[i] = 0;
  51. }
  52. return arr;
  53. }
  54. /* Will be overridden with real function */
  55. new_imageData = function() {
  56. throw("imageData not supported");
  57. };
  58. new_imageData_createImageData = function() {
  59. var imageData = ctx.createImageData(1024/4, arraySize / 1024);
  60. return imageData.data;
  61. };
  62. new_imageData_getImageData = function() {
  63. var imageData = ctx.getImageData(0, 0, 1024/4, arraySize / 1024),
  64. arr = imageData.data;
  65. for (i = 0; i < arraySize; i++) {
  66. arr[i] = 0;
  67. }
  68. return arr;
  69. };
  70. new_arrayBuffer = function() {
  71. var arr = new ArrayBuffer(arraySize);
  72. return new Uint8Array(arr);
  73. }
  74. function init_randlist() {
  75. randlist = [];
  76. for (var i=0; i < arraySize; i++) {
  77. randlist[i] = parseInt(Math.random() * 256, 10);
  78. }
  79. }
  80. function copy_randlist(arr) {
  81. for (var i=0; i < arraySize; i++) {
  82. arr[i] = randlist[i];
  83. }
  84. }
  85. function begin() {
  86. var i, j;
  87. conf.iterations = parseInt($D('iterations').value, 10);
  88. arraySize = parseInt($D('arraySize').value, 10) * 1024;
  89. init_randlist();
  90. // TODO: randomize test_list
  91. stats = {};
  92. for (i = 0; i < conf.order_l2.length; i++) {
  93. stats[conf.order_l2[i]] = {};
  94. for (j = 0; j < conf.order_l3.length; j++) {
  95. stats[conf.order_l2[i]][conf.order_l3[j]] = [];
  96. }
  97. }
  98. $D('startButton').value = "Running";
  99. $D('startButton').disabled = true;
  100. message("running " + conf.iterations + " test iterations");
  101. iteration = 1;
  102. setTimeout(run_next_iteration, 250);
  103. }
  104. function finish() {
  105. var totalTime, arrayType, testType, times;
  106. message("tests finished");
  107. for (j = 0; j < conf.order_l3.length; j++) {
  108. testType = conf.order_l3[j];
  109. message("Test '" + testType + "'");
  110. for (i = 0; i < conf.order_l2.length; i++) {
  111. arrayType = conf.order_l2[i];
  112. message(" Array Type '" + arrayType);
  113. times = stats[arrayType][testType];
  114. message(" Average : " + times.mean() + "ms" +
  115. " (Total: " + times.sum() + "ms)");
  116. message(" Min/Max : " + times.min() + "ms/" +
  117. times.max() + "ms");
  118. message(" StdDev : " + times.stdDev() + "ms");
  119. }
  120. }
  121. vmessage("array_chart.py JSON data:");
  122. chart_data = {'conf' : conf, 'stats' : { } };
  123. chart_data.stats[browser] = stats;
  124. chart_data.stats['next_browser'] = {};
  125. vmessage(JSON.stringify(chart_data, null, 2));
  126. $D('startButton').disabled = false;
  127. $D('startButton').value = "Run Tests";
  128. }
  129. function run_next_iteration() {
  130. var arrayType, testType, deltaTime;
  131. for (i = 0; i < conf.order_l2.length; i++) {
  132. arrayType = conf.order_l2[i];
  133. if (arrayType === 'imageData' && (!do_imageData)) {
  134. continue;
  135. }
  136. if (arrayType === 'arrayBuffer' && (!do_arrayBuffer)) {
  137. continue;
  138. }
  139. for (j = 0; j < conf.order_l3.length; j++) {
  140. testType = conf.order_l3[j];
  141. deltaTime = testFunc[arrayType + "_" + testType]();
  142. stats[arrayType][testType].push(deltaTime);
  143. vmessage("test " + (arrayType + "_" + testType) +
  144. " time: " + (deltaTime) + "ms");
  145. }
  146. }
  147. message("finished test iteration " + iteration);
  148. if (iteration >= conf.iterations) {
  149. setTimeout(finish, 1);
  150. return;
  151. }
  152. iteration++;
  153. setTimeout(run_next_iteration, 1);
  154. }
  155. /*
  156. * Test functions
  157. */
  158. testFunc["normal_create"] = function() {
  159. var cnt, arrNormal, startTime, endTime;
  160. vmessage("create normal array " + conf.create_cnt + "x, initialized to 0");
  161. startTime = (new Date()).getTime();
  162. for (cnt = 0; cnt < conf.create_cnt; cnt++) {
  163. arrNormal = new_normal();
  164. }
  165. endTime = (new Date()).getTime();
  166. return endTime - startTime;
  167. };
  168. testFunc["imageData_create"] = function() {
  169. var cnt, arrImage, startTime, endTime;
  170. vmessage("create imageData array " + conf.create_cnt + "x, initialized to 0");
  171. startTime = (new Date()).getTime();
  172. for (cnt = 0; cnt < conf.create_cnt; cnt++) {
  173. arrImage = new_imageData();
  174. }
  175. endTime = (new Date()).getTime();
  176. if (arrImage[103] !== 0) {
  177. message("Initialization failed, arrImage[103] is: " + arrImage[103]);
  178. throw("Initialization failed, arrImage[103] is: " + arrImage[103]);
  179. }
  180. return endTime - startTime;
  181. };
  182. testFunc["arrayBuffer_create"] = function() {
  183. var cnt, arrBuffer, startTime, endTime;
  184. vmessage("create arrayBuffer array " + conf.create_cnt + "x, initialized to 0");
  185. startTime = (new Date()).getTime();
  186. for (cnt = 0; cnt < conf.create_cnt; cnt++) {
  187. arrBuffer = new_arrayBuffer();
  188. }
  189. endTime = (new Date()).getTime();
  190. if (arrBuffer[103] !== 0) {
  191. message("Initialization failed, arrBuffer[103] is: " + arrBuffer[103]);
  192. throw("Initialization failed, arrBuffer[103] is: " + arrBuffer[103]);
  193. }
  194. return endTime - startTime;
  195. };
  196. function test_sequentialRead(arr) {
  197. var i, j, cnt, startTime, endTime;
  198. /* Initialize the array */
  199. copy_randlist(arr);
  200. startTime = (new Date()).getTime();
  201. i = 0;
  202. j = 0;
  203. for (cnt = 0; cnt < conf.read_cnt; cnt++) {
  204. j = arr[i];
  205. i++;
  206. if (i >= arraySize) {
  207. i = 0;
  208. }
  209. }
  210. endTime = (new Date()).getTime();
  211. return endTime - startTime;
  212. }
  213. function test_randomRead(arr) {
  214. var i, cnt, startTime, endTime;
  215. /* Initialize the array */
  216. copy_randlist(arr); // used as jumplist
  217. startTime = (new Date()).getTime();
  218. i = 0;
  219. for (cnt = 0; cnt < conf.read_cnt; cnt++) {
  220. i = (arr[i] + cnt) % arraySize;
  221. }
  222. endTime = (new Date()).getTime();
  223. return endTime - startTime;
  224. }
  225. function test_sequentialWrite(arr) {
  226. var i, cnt, startTime, endTime;
  227. /* Initialize the array */
  228. copy_randlist(arr);
  229. startTime = (new Date()).getTime();
  230. i = 0;
  231. for (cnt = 0; cnt < conf.write_cnt; cnt++) {
  232. arr[i] = (cnt % 256);
  233. i++;
  234. if (i >= arraySize) {
  235. i = 0;
  236. }
  237. }
  238. endTime = (new Date()).getTime();
  239. return endTime - startTime;
  240. }
  241. /* Sequential Read Tests */
  242. testFunc["normal_sequentialRead"] = function() {
  243. vmessage("read normal array " + conf.read_cnt + "x");
  244. return test_sequentialRead(new_normal());
  245. };
  246. testFunc["imageData_sequentialRead"] = function() {
  247. vmessage("read imageData array " + conf.read_cnt + "x");
  248. return test_sequentialRead(new_imageData());
  249. };
  250. testFunc["arrayBuffer_sequentialRead"] = function() {
  251. vmessage("read arrayBuffer array " + conf.read_cnt + "x");
  252. return test_sequentialRead(new_arrayBuffer());
  253. };
  254. /* Random Read Tests */
  255. testFunc["normal_randomRead"] = function() {
  256. vmessage("read normal array " + conf.read_cnt + "x");
  257. return test_randomRead(new_normal());
  258. };
  259. testFunc["imageData_randomRead"] = function() {
  260. vmessage("read imageData array " + conf.read_cnt + "x");
  261. return test_randomRead(new_imageData());
  262. };
  263. testFunc["arrayBuffer_randomRead"] = function() {
  264. vmessage("read arrayBuffer array " + conf.read_cnt + "x");
  265. return test_randomRead(new_arrayBuffer());
  266. };
  267. /* Sequential Write Tests */
  268. testFunc["normal_sequentialWrite"] = function() {
  269. vmessage("write normal array " + conf.write_cnt + "x");
  270. return test_sequentialWrite(new_normal());
  271. };
  272. testFunc["imageData_sequentialWrite"] = function() {
  273. vmessage("write imageData array " + conf.write_cnt + "x");
  274. return test_sequentialWrite(new_imageData());
  275. };
  276. testFunc["arrayBuffer_sequentialWrite"] = function() {
  277. vmessage("write arrayBuffer array " + conf.write_cnt + "x");
  278. return test_sequentialWrite(new_arrayBuffer());
  279. };
  280. init = function() {
  281. vmessage(">> init");
  282. $D('iterations').value = 10;
  283. $D('arraySize').value = 10;
  284. arraySize = parseInt($D('arraySize').value, 10) * 1024;
  285. message("Browser: " + browser);
  286. /* Determine browser binary array support */
  287. try {
  288. ctx = $D('canvas').getContext('2d');
  289. new_imageData = new_imageData_createImageData;
  290. new_imageData();
  291. do_imageData = true;
  292. } catch (exc) {
  293. vmessage("createImageData not supported: " + exc);
  294. try {
  295. ctx = $D('canvas').getContext('2d');
  296. new_imageData = new_imageData_getImageData;
  297. blah = new_imageData();
  298. do_imageData = true;
  299. } catch (exc) {
  300. vmessage("getImageData not supported: " + exc);
  301. }
  302. }
  303. if (! do_imageData) {
  304. message("imageData arrays not supported");
  305. }
  306. try {
  307. new_arrayBuffer();
  308. do_arrayBuffer = true;
  309. } catch (exc) {
  310. vmessage("Typed Arrays not supported: " + exc);
  311. }
  312. if (! do_arrayBuffer) {
  313. message("Typed Arrays (ArrayBuffers) not suppoted");
  314. }
  315. vmessage("<< init");
  316. }