Add Javascript binary byte array test.
Compares normal Javascript arrays with Canvas ImageData arrays and Typed Arrays (ArrayBuffers from WebGL).
This commit is contained in:
parent
ed6a3f8518
commit
7fbab7473c
|
@ -0,0 +1,39 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Javascript Arrays Performance Test</title>
|
||||||
|
<!--
|
||||||
|
<script type='text/javascript'
|
||||||
|
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
|
||||||
|
-->
|
||||||
|
<script src="include/util.js"></script>
|
||||||
|
<script src="include/webutil.js"></script>
|
||||||
|
<script src="browser.js"></script>
|
||||||
|
<script src="stats.js"></script>
|
||||||
|
<script src="arrays.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h3>Javascript Arrays Performance Test</h3>
|
||||||
|
Iterations: <input id='iterations' style='width:50'>
|
||||||
|
Array Size: <input id='arraySize' style='width:40'>*1024
|
||||||
|
|
||||||
|
<input id='startButton' type='button' value='Run Tests'
|
||||||
|
onclick="begin();">
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
Results:<br>
|
||||||
|
<textarea id="messages" style="font-size: 9;" cols=80 rows=50></textarea>
|
||||||
|
</br>
|
||||||
|
<canvas id="canvas" style="display: none;"></canvas>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var verbose = true;
|
||||||
|
window.onload = function() {
|
||||||
|
vmessage("in onload");
|
||||||
|
init();
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</html>
|
|
@ -0,0 +1,369 @@
|
||||||
|
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 = "<br>\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");
|
||||||
|
}
|
|
@ -0,0 +1,199 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# a bar plot with errorbars
|
||||||
|
import sys, json, pprint
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from matplotlib.font_manager import FontProperties
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
print "%s json_file level1 level2 level3\n\n" % sys.argv[0]
|
||||||
|
print "Description:\n"
|
||||||
|
print "level1, level2, and level3 are one each of the following:\n";
|
||||||
|
print " select=ITEM - select only ITEM at this level";
|
||||||
|
print " bar - each item on this level becomes a graph bar";
|
||||||
|
print " group - items on this level become groups of bars";
|
||||||
|
print "\n";
|
||||||
|
print "json_file is a file containing json data in the following format:\n"
|
||||||
|
print ' {';
|
||||||
|
print ' "conf": {';
|
||||||
|
print ' "order_l1": [';
|
||||||
|
print ' "level1_label1",';
|
||||||
|
print ' "level1_label2",';
|
||||||
|
print ' ...';
|
||||||
|
print ' ],';
|
||||||
|
print ' "order_l2": [';
|
||||||
|
print ' "level2_label1",';
|
||||||
|
print ' "level2_label2",';
|
||||||
|
print ' ...';
|
||||||
|
print ' ],';
|
||||||
|
print ' "order_l3": [';
|
||||||
|
print ' "level3_label1",';
|
||||||
|
print ' "level3_label2",';
|
||||||
|
print ' ...';
|
||||||
|
print ' ]';
|
||||||
|
print ' },';
|
||||||
|
print ' "stats": {';
|
||||||
|
print ' "level1_label1": {';
|
||||||
|
print ' "level2_label1": {';
|
||||||
|
print ' "level3_label1": [val1, val2, val3],';
|
||||||
|
print ' "level3_label2": [val1, val2, val3],';
|
||||||
|
print ' ...';
|
||||||
|
print ' },';
|
||||||
|
print ' "level2_label2": {';
|
||||||
|
print ' ...';
|
||||||
|
print ' },';
|
||||||
|
print ' },';
|
||||||
|
print ' "level1_label2": {';
|
||||||
|
print ' ...';
|
||||||
|
print ' },';
|
||||||
|
print ' ...';
|
||||||
|
print ' },';
|
||||||
|
print ' }';
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
def error(msg):
|
||||||
|
print msg
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
#colors = ['#ff0000', '#0863e9', '#00f200', '#ffa100',
|
||||||
|
# '#800000', '#805100', '#013075', '#007900']
|
||||||
|
colors = ['#ff0000', '#00ff00', '#0000ff',
|
||||||
|
'#dddd00', '#dd00dd', '#00dddd',
|
||||||
|
'#dd6622', '#dd2266', '#66dd22',
|
||||||
|
'#8844dd', '#44dd88', '#4488dd']
|
||||||
|
|
||||||
|
if len(sys.argv) < 5:
|
||||||
|
usage()
|
||||||
|
|
||||||
|
filename = sys.argv[1]
|
||||||
|
L1 = sys.argv[2]
|
||||||
|
L2 = sys.argv[3]
|
||||||
|
L3 = sys.argv[4]
|
||||||
|
if len(sys.argv) > 5:
|
||||||
|
legendHeight = float(sys.argv[5])
|
||||||
|
else:
|
||||||
|
legendHeight = 0.75
|
||||||
|
|
||||||
|
# Load the JSON data from the file
|
||||||
|
data = json.loads(file(filename).read())
|
||||||
|
conf = data['conf']
|
||||||
|
stats = data['stats']
|
||||||
|
|
||||||
|
# Sanity check data hierarchy
|
||||||
|
if len(conf['order_l1']) != len(stats.keys()):
|
||||||
|
error("conf.order_l1 does not match stats level 1")
|
||||||
|
for l1 in stats.keys():
|
||||||
|
if len(conf['order_l2']) != len(stats[l1].keys()):
|
||||||
|
error("conf.order_l2 does not match stats level 2 for %s" % l1)
|
||||||
|
if conf['order_l1'].count(l1) < 1:
|
||||||
|
error("%s not found in conf.order_l1" % l1)
|
||||||
|
for l2 in stats[l1].keys():
|
||||||
|
if len(conf['order_l3']) != len(stats[l1][l2].keys()):
|
||||||
|
error("conf.order_l3 does not match stats level 3")
|
||||||
|
if conf['order_l2'].count(l2) < 1:
|
||||||
|
error("%s not found in conf.order_l2" % l2)
|
||||||
|
for l3 in stats[l1][l2].keys():
|
||||||
|
if conf['order_l3'].count(l3) < 1:
|
||||||
|
error("%s not found in conf.order_l3" % l3)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate the data based on the level specifications
|
||||||
|
#
|
||||||
|
bar_labels = None
|
||||||
|
group_labels = None
|
||||||
|
bar_vals = []
|
||||||
|
bar_sdvs = []
|
||||||
|
if L3.startswith("select="):
|
||||||
|
select_label = l3 = L3.split("=")[1]
|
||||||
|
bar_labels = conf['order_l1']
|
||||||
|
group_labels = conf['order_l2']
|
||||||
|
bar_vals = [[0]*len(group_labels) for i in bar_labels]
|
||||||
|
bar_sdvs = [[0]*len(group_labels) for i in bar_labels]
|
||||||
|
for b in range(len(bar_labels)):
|
||||||
|
l1 = bar_labels[b]
|
||||||
|
for g in range(len(group_labels)):
|
||||||
|
l2 = group_labels[g]
|
||||||
|
bar_vals[b][g] = np.mean(stats[l1][l2][l3])
|
||||||
|
bar_sdvs[b][g] = np.std(stats[l1][l2][l3])
|
||||||
|
elif L2.startswith("select="):
|
||||||
|
select_label = l2 = L2.split("=")[1]
|
||||||
|
bar_labels = conf['order_l1']
|
||||||
|
group_labels = conf['order_l3']
|
||||||
|
bar_vals = [[0]*len(group_labels) for i in bar_labels]
|
||||||
|
bar_sdvs = [[0]*len(group_labels) for i in bar_labels]
|
||||||
|
for b in range(len(bar_labels)):
|
||||||
|
l1 = bar_labels[b]
|
||||||
|
for g in range(len(group_labels)):
|
||||||
|
l3 = group_labels[g]
|
||||||
|
bar_vals[b][g] = np.mean(stats[l1][l2][l3])
|
||||||
|
bar_sdvs[b][g] = np.std(stats[l1][l2][l3])
|
||||||
|
elif L1.startswith("select="):
|
||||||
|
select_label = l1 = L1.split("=")[1]
|
||||||
|
bar_labels = conf['order_l2']
|
||||||
|
group_labels = conf['order_l3']
|
||||||
|
bar_vals = [[0]*len(group_labels) for i in bar_labels]
|
||||||
|
bar_sdvs = [[0]*len(group_labels) for i in bar_labels]
|
||||||
|
for b in range(len(bar_labels)):
|
||||||
|
l2 = bar_labels[b]
|
||||||
|
for g in range(len(group_labels)):
|
||||||
|
l3 = group_labels[g]
|
||||||
|
bar_vals[b][g] = np.mean(stats[l1][l2][l3])
|
||||||
|
bar_sdvs[b][g] = np.std(stats[l1][l2][l3])
|
||||||
|
else:
|
||||||
|
usage()
|
||||||
|
|
||||||
|
# If group is before bar then flip (zip) the data
|
||||||
|
if [L1, L2, L3].index("group") < [L1, L2, L3].index("bar"):
|
||||||
|
bar_labels, group_labels = group_labels, bar_labels
|
||||||
|
bar_vals = zip(*bar_vals)
|
||||||
|
bar_sdvs = zip(*bar_sdvs)
|
||||||
|
|
||||||
|
print "bar_vals:", bar_vals
|
||||||
|
|
||||||
|
#
|
||||||
|
# Now render the bar graph
|
||||||
|
#
|
||||||
|
ind = np.arange(len(group_labels)) # the x locations for the groups
|
||||||
|
width = 0.8 * (1.0/len(bar_labels)) # the width of the bars
|
||||||
|
|
||||||
|
fig = plt.figure(figsize=(10,6), dpi=80)
|
||||||
|
plot = fig.add_subplot(1, 1, 1)
|
||||||
|
|
||||||
|
rects = []
|
||||||
|
for i in range(len(bar_vals)):
|
||||||
|
rects.append(plot.bar(ind+width*i, bar_vals[i], width, color=colors[i],
|
||||||
|
yerr=bar_sdvs[i], align='center'))
|
||||||
|
|
||||||
|
# add some
|
||||||
|
plot.set_ylabel('Milliseconds (less is better)')
|
||||||
|
plot.set_title("Javascript array test: %s" % select_label)
|
||||||
|
plot.set_xticks(ind+width)
|
||||||
|
plot.set_xticklabels( group_labels )
|
||||||
|
|
||||||
|
fontP = FontProperties()
|
||||||
|
fontP.set_size('small')
|
||||||
|
plot.legend( [r[0] for r in rects], bar_labels, prop=fontP,
|
||||||
|
loc = 'center right', bbox_to_anchor = (1.0, legendHeight))
|
||||||
|
|
||||||
|
def autolabel(rects):
|
||||||
|
# attach some text labels
|
||||||
|
for rect in rects:
|
||||||
|
height = rect.get_height()
|
||||||
|
if np.isnan(height):
|
||||||
|
height = 0.0
|
||||||
|
plot.text(rect.get_x()+rect.get_width()/2., height+20, '%d'%int(height),
|
||||||
|
ha='center', va='bottom', size='7')
|
||||||
|
|
||||||
|
for rect in rects:
|
||||||
|
autolabel(rect)
|
||||||
|
|
||||||
|
# Adjust axis sizes
|
||||||
|
axis = list(plot.axis())
|
||||||
|
axis[0] = -width # Make sure left side has enough for bar
|
||||||
|
#axis[1] = axis[1] * 1.20 # Add 20% to the right to make sure it fits
|
||||||
|
axis[2] = 0 # Make y-axis start at 0
|
||||||
|
axis[3] = axis[3] * 1.10 # Add 10% to the top
|
||||||
|
plot.axis(axis)
|
||||||
|
|
||||||
|
plt.show()
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Define some useful statistical functions on arrays of numbers
|
||||||
|
*/
|
||||||
|
|
||||||
|
Array.prototype.sum = function() {
|
||||||
|
var i, sum = 0;
|
||||||
|
for (i = 0; i < this.length; i++) {
|
||||||
|
sum += this[i];
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.prototype.max = function() {
|
||||||
|
return Math.max.apply(null, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.prototype.min = function() {
|
||||||
|
return Math.min.apply(null, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.prototype.mean = function() {
|
||||||
|
return this.sum() / this.length;
|
||||||
|
}
|
||||||
|
Array.prototype.average = Array.prototype.mean;
|
||||||
|
|
||||||
|
Array.prototype.median = function() {
|
||||||
|
var sorted = this.sort( function(a,b) { return a-b; }),
|
||||||
|
len = sorted.length;
|
||||||
|
if (len % 2) {
|
||||||
|
return sorted[Math.floor(len / 2)]; // Odd
|
||||||
|
} else {
|
||||||
|
return (sorted[len/2 - 1] + sorted[len/2]) / 2; // Even
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.prototype.stdDev = function(sample) {
|
||||||
|
var i, sumSqr = 0, mean = this.mean(), N;
|
||||||
|
|
||||||
|
if (sample) {
|
||||||
|
// Population correction if this is a sample
|
||||||
|
N = this.length - 1;
|
||||||
|
} else {
|
||||||
|
// Standard deviation of just the array
|
||||||
|
N = this.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < this.length; i++) {
|
||||||
|
sumSqr += Math.pow(this[i] - mean, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.sqrt(sumSqr / N);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue