/* * Javascript binary array performance tests * Copyright (C) 2012 Joel Martin * Licensed under MPL 2.0 (see LICENSE.txt) */ var ctx, i, j, randlist, new_normal, new_imageData, new_arrayBuffer, browser = Browser.browser + " " + Browser.version + " on " + Browser.OS, do_imageData = false, do_arrayBuffer = false, conf = { 'create_cnt' : 2000, 'read_cnt' : 5000000, 'write_cnt' : 5000000, 'iterations' : 0, 'order_l1' : [browser], 'order_l2' : ['normal', 'imageData', 'arrayBuffer'], 'order_l3' : ['create', 'sequentialRead', 'randomRead', 'sequentialWrite'] }, stats = {}, testFunc = {}, iteration, arraySize; var newline = "\n"; if (Util.Engine.trident) { var newline = "
\n"; } function message(str) { //console.log(str); cell = $D('messages'); cell.innerHTML += str + newline; cell.scrollTop = cell.scrollHeight; } function vmessage(str) { if (verbose) { message(str); } else { console.log(str); } } new_normal = function() { var arr = [], i; for (i = 0; i < arraySize; i++) { arr[i] = 0; } return arr; } /* Will be overridden with real function */ new_imageData = function() { throw("imageData not supported"); }; new_imageData_createImageData = function() { var imageData = ctx.createImageData(1024/4, arraySize / 1024); return imageData.data; }; new_imageData_getImageData = function() { var imageData = ctx.getImageData(0, 0, 1024/4, arraySize / 1024), arr = imageData.data; for (i = 0; i < arraySize; i++) { arr[i] = 0; } return arr; }; new_arrayBuffer = function() { var arr = new ArrayBuffer(arraySize); return new Uint8Array(arr); } function init_randlist() { randlist = []; for (var i=0; i < arraySize; i++) { randlist[i] = parseInt(Math.random() * 256, 10); } } function copy_randlist(arr) { for (var i=0; i < arraySize; i++) { arr[i] = randlist[i]; } } function begin() { var i, j; conf.iterations = parseInt($D('iterations').value, 10); arraySize = parseInt($D('arraySize').value, 10) * 1024; init_randlist(); // TODO: randomize test_list stats = {}; for (i = 0; i < conf.order_l2.length; i++) { stats[conf.order_l2[i]] = {}; for (j = 0; j < conf.order_l3.length; j++) { stats[conf.order_l2[i]][conf.order_l3[j]] = []; } } $D('startButton').value = "Running"; $D('startButton').disabled = true; message("running " + conf.iterations + " test iterations"); iteration = 1; setTimeout(run_next_iteration, 250); } function finish() { var totalTime, arrayType, testType, times; message("tests finished"); for (j = 0; j < conf.order_l3.length; j++) { testType = conf.order_l3[j]; message("Test '" + testType + "'"); for (i = 0; i < conf.order_l2.length; i++) { arrayType = conf.order_l2[i]; message(" Array Type '" + arrayType); times = stats[arrayType][testType]; message(" Average : " + times.mean() + "ms" + " (Total: " + times.sum() + "ms)"); message(" Min/Max : " + times.min() + "ms/" + times.max() + "ms"); message(" StdDev : " + times.stdDev() + "ms"); } } vmessage("array_chart.py JSON data:"); chart_data = {'conf' : conf, 'stats' : { } }; chart_data.stats[browser] = stats; chart_data.stats['next_browser'] = {}; vmessage(JSON.stringify(chart_data, null, 2)); $D('startButton').disabled = false; $D('startButton').value = "Run Tests"; } function run_next_iteration() { var arrayType, testType, deltaTime; for (i = 0; i < conf.order_l2.length; i++) { arrayType = conf.order_l2[i]; if (arrayType === 'imageData' && (!do_imageData)) { continue; } if (arrayType === 'arrayBuffer' && (!do_arrayBuffer)) { continue; } for (j = 0; j < conf.order_l3.length; j++) { testType = conf.order_l3[j]; deltaTime = testFunc[arrayType + "_" + testType](); stats[arrayType][testType].push(deltaTime); vmessage("test " + (arrayType + "_" + testType) + " time: " + (deltaTime) + "ms"); } } message("finished test iteration " + iteration); if (iteration >= conf.iterations) { setTimeout(finish, 1); return; } iteration++; setTimeout(run_next_iteration, 1); } /* * Test functions */ testFunc["normal_create"] = function() { var cnt, arrNormal, startTime, endTime; vmessage("create normal array " + conf.create_cnt + "x, initialized to 0"); startTime = (new Date()).getTime(); for (cnt = 0; cnt < conf.create_cnt; cnt++) { arrNormal = new_normal(); } endTime = (new Date()).getTime(); return endTime - startTime; }; testFunc["imageData_create"] = function() { var cnt, arrImage, startTime, endTime; vmessage("create imageData array " + conf.create_cnt + "x, initialized to 0"); startTime = (new Date()).getTime(); for (cnt = 0; cnt < conf.create_cnt; cnt++) { arrImage = new_imageData(); } endTime = (new Date()).getTime(); if (arrImage[103] !== 0) { message("Initialization failed, arrImage[103] is: " + arrImage[103]); throw("Initialization failed, arrImage[103] is: " + arrImage[103]); } return endTime - startTime; }; testFunc["arrayBuffer_create"] = function() { var cnt, arrBuffer, startTime, endTime; vmessage("create arrayBuffer array " + conf.create_cnt + "x, initialized to 0"); startTime = (new Date()).getTime(); for (cnt = 0; cnt < conf.create_cnt; cnt++) { arrBuffer = new_arrayBuffer(); } endTime = (new Date()).getTime(); if (arrBuffer[103] !== 0) { message("Initialization failed, arrBuffer[103] is: " + arrBuffer[103]); throw("Initialization failed, arrBuffer[103] is: " + arrBuffer[103]); } return endTime - startTime; }; function test_sequentialRead(arr) { var i, j, cnt, startTime, endTime; /* Initialize the array */ copy_randlist(arr); startTime = (new Date()).getTime(); i = 0; j = 0; for (cnt = 0; cnt < conf.read_cnt; cnt++) { j = arr[i]; i++; if (i >= arraySize) { i = 0; } } endTime = (new Date()).getTime(); return endTime - startTime; } function test_randomRead(arr) { var i, cnt, startTime, endTime; /* Initialize the array */ copy_randlist(arr); // used as jumplist startTime = (new Date()).getTime(); i = 0; for (cnt = 0; cnt < conf.read_cnt; cnt++) { i = (arr[i] + cnt) % arraySize; } endTime = (new Date()).getTime(); return endTime - startTime; } function test_sequentialWrite(arr) { var i, cnt, startTime, endTime; /* Initialize the array */ copy_randlist(arr); startTime = (new Date()).getTime(); i = 0; for (cnt = 0; cnt < conf.write_cnt; cnt++) { arr[i] = (cnt % 256); i++; if (i >= arraySize) { i = 0; } } endTime = (new Date()).getTime(); return endTime - startTime; } /* Sequential Read Tests */ testFunc["normal_sequentialRead"] = function() { vmessage("read normal array " + conf.read_cnt + "x"); return test_sequentialRead(new_normal()); }; testFunc["imageData_sequentialRead"] = function() { vmessage("read imageData array " + conf.read_cnt + "x"); return test_sequentialRead(new_imageData()); }; testFunc["arrayBuffer_sequentialRead"] = function() { vmessage("read arrayBuffer array " + conf.read_cnt + "x"); return test_sequentialRead(new_arrayBuffer()); }; /* Random Read Tests */ testFunc["normal_randomRead"] = function() { vmessage("read normal array " + conf.read_cnt + "x"); return test_randomRead(new_normal()); }; testFunc["imageData_randomRead"] = function() { vmessage("read imageData array " + conf.read_cnt + "x"); return test_randomRead(new_imageData()); }; testFunc["arrayBuffer_randomRead"] = function() { vmessage("read arrayBuffer array " + conf.read_cnt + "x"); return test_randomRead(new_arrayBuffer()); }; /* Sequential Write Tests */ testFunc["normal_sequentialWrite"] = function() { vmessage("write normal array " + conf.write_cnt + "x"); return test_sequentialWrite(new_normal()); }; testFunc["imageData_sequentialWrite"] = function() { vmessage("write imageData array " + conf.write_cnt + "x"); return test_sequentialWrite(new_imageData()); }; testFunc["arrayBuffer_sequentialWrite"] = function() { vmessage("write arrayBuffer array " + conf.write_cnt + "x"); return test_sequentialWrite(new_arrayBuffer()); }; init = function() { vmessage(">> init"); $D('iterations').value = 10; $D('arraySize').value = 10; arraySize = parseInt($D('arraySize').value, 10) * 1024; message("Browser: " + browser); /* Determine browser binary array support */ try { ctx = $D('canvas').getContext('2d'); new_imageData = new_imageData_createImageData; new_imageData(); do_imageData = true; } catch (exc) { vmessage("createImageData not supported: " + exc); try { ctx = $D('canvas').getContext('2d'); new_imageData = new_imageData_getImageData; blah = new_imageData(); do_imageData = true; } catch (exc) { vmessage("getImageData not supported: " + exc); } } if (! do_imageData) { message("imageData arrays not supported"); } try { new_arrayBuffer(); do_arrayBuffer = true; } catch (exc) { vmessage("Typed Arrays not supported: " + exc); } if (! do_arrayBuffer) { message("Typed Arrays (ArrayBuffers) not suppoted"); } vmessage("<< init"); }