Skip to content

Commit c7b4864

Browse files
committed
add sortable table of results
1 parent 85a3c32 commit c7b4864

File tree

9 files changed

+880
-3
lines changed

9 files changed

+880
-3
lines changed

blank.cur

78 Bytes
Binary file not shown.

images/destroy.png

555 Bytes
Loading

images/tablesort/down.gif

57 Bytes
Loading

images/tablesort/up.gif

56 Bytes
Loading

matrix_benchmark.html

+102-3
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,26 @@
55
<title>Matrix Benchmark</title>
66

77
<!-- Common Utilities -->
8+
<script type="text/javascript" src="sprintf.js"></script>
9+
10+
<!-- Matrix Libraries -->
811
<script type="text/javascript" src="js/glMatrix.js"></script>
912
<script type="text/javascript" src="js/CanvasMatrix.js"></script>
1013
<script type="text/javascript" src="js/EWGL_math.js"></script>
1114
<script type="text/javascript" src="js/mjs.js"></script>
1215
<script type="text/javascript" src="js/tdl/base.js"></script>
1316

1417
<!-- Graphing Utilities -->
18+
<link type="text/css" rel="stylesheet" href="flotr/flotr.css"/>
1519
<script type="text/javascript" src="flotr/lib/prototype.js"></script>
1620
<script type="text/javascript" src="flotr/lib/canvas2image.js"></script>
1721
<script type="text/javascript" src="flotr/lib/canvastext.js"></script>
1822
<script type="text/javascript" src="flotr/flotr.js"></script>
23+
24+
<!-- Table Utilities -->
25+
<link type="text/css" rel="stylesheet" href="table/table.css"/>
26+
<script type="text/javascript" src="table/fastinit.js"></script>
27+
<script type="text/javascript" src="table/tablesort.js"></script>
1928

2029
<!-- Benchmarking utilities -->
2130
<script type="text/javascript">
@@ -79,7 +88,10 @@
7988
test(tests[i].library, tests[i].test, testData[name]);
8089
}
8190
}, 1);
82-
setTimeout(function() { plotBenchmarks() }, 1);
91+
setTimeout(function() {
92+
plotBenchmarks();
93+
updateTableData();
94+
}, 1);
8395
}
8496

8597
function glMatrixRandom() {
@@ -166,9 +178,18 @@
166178
Benchmark times are averaged over 10 runs of 20,000 iterations of the target operation.<br/>
167179
</p>
168180
<div id="graph" style="width:800px;height:400px;margin:10px"></div>
181+
<div id="tablediv" style="font-size:85%;width:800px;margin:10px">
182+
<table id='data-table' class='sortable'>
183+
<thead id="data-table-head">
184+
<tr></tr>
185+
</thead>
186+
<tbody id="data-table-body"></tbody>
187+
</table>
188+
</div>
169189
<p><em>
170190
Adapted from the benchmarks Brandon Jones created in his <a href=" https://glmatrix.googlecode.com/hg/">glmatrix library</a>.<br/>
171-
JavaScript Plotting library: <a href=" http://solutoire.com/flotr/">Flotr</a>.<br/>
191+
JavaScript Plotting library: <a href=" http://solutoire.com/flotr/">Flotr</a>;
192+
<a href="http://tetlaw.id.au/view/blog/table-sorting-with-prototype/">Sortable Table</a> by Andrew Tetlaw.<br/>
172193
The source code for these benchmarks can be found here on <a href="https://github.com/stepheneb/webgl-matrix-benchmarks">github</a>.
173194
</em></p>
174195
<br/><br/>
@@ -670,11 +691,12 @@
670691
]);
671692
};
672693

694+
673695
function plotBenchmarks() {
674696
var datasets = [];
697+
var benchmarks = [];
675698
var benchmarkIndex, libraryIndex;
676699
benchmarkIndex = 0;
677-
var benchmarks = [];
678700
var x_axis_tics = [];
679701
for (benchmark in testData) {
680702
benchmarks.push(benchmark);
@@ -725,11 +747,88 @@
725747
}
726748
);
727749
};
750+
751+
var data_table_head = document.getElementById("data-table-head");
752+
var data_table_body = document.getElementById("data-table-body");
753+
754+
var libraries = ["glMatrix", "mjs", "CanvasMatrix", "EWGL", "TDLMath", "TDLFast"];
755+
756+
function library_to_id(library) {
757+
return library.toLowerCase().replace(/\W/g, '_');
758+
}
759+
760+
function createTableData() {
761+
var row, data, header;
762+
row = document.createElement('tr');
763+
header = document.createElement('th');
764+
header.className = "text sortcol";
765+
header.textContent = "Library";
766+
row.appendChild(header);
767+
for(benchmark in testData) {
768+
header = document.createElement('th');
769+
header.className = "number sortcol";
770+
header.textContent = benchmark;
771+
row.appendChild(header);
772+
};
773+
header = document.createElement('th');
774+
header.className = "number sortcol";
775+
header.textContent = "Average";
776+
row.appendChild(header);
777+
data_table_head.deleteRow(0)
778+
data_table_head.appendChild(row);
779+
780+
for (i = 0; i < libraries.length; i++) {
781+
row = document.createElement('tr');
782+
row.id = libraries[i] + '_row';
783+
data = document.createElement('td');
784+
data.textContent = libraries[i];
785+
row.appendChild(data);
786+
for(benchmark in testData) {
787+
data = document.createElement('td');
788+
data.id = benchmark + '_' + library_to_id(libraries[i]) + '_data'
789+
data.textContent = "";
790+
row.appendChild(data);
791+
};
792+
data = document.createElement('td');
793+
data.id = library_to_id(libraries[i]) + '_ave__data'
794+
data.textContent = "";
795+
row.appendChild(data);
796+
data_table_body.appendChild(row);
797+
};
798+
};
799+
800+
var averages = {};
801+
802+
function updateTableData() {
803+
var row, data, value, average;
804+
for(benchmark in testData) {
805+
for (library in testData[benchmark]) {
806+
data = document.getElementById(benchmark + '_' + library_to_id(library) + '_data');
807+
value = testData[benchmark][library].avg;
808+
data.textContent = value;
809+
average = averages[library];
810+
if (typeof(average) === "number" && typeof(value) === "number") {
811+
averages[library] = (average + value) / 2;
812+
} else {
813+
averages[library] = value;
814+
}
815+
};
816+
};
817+
for (library in averages) {
818+
if (averages[library]) {
819+
data = document.getElementById(library_to_id(library) + '_ave__data');
820+
data.textContent = sprintf("%3.1f", averages[library]);
821+
};
822+
};
823+
SortableTable.load();
824+
};
825+
728826
</script>
729827
<script type="text/javascript">
730828
window.onload=function() {
731829
testMain();
732830
plotBenchmarks();
831+
createTableData();
733832
setTimeout(function() { plotBenchmarks() }, 1);
734833
}
735834
</script>

sprintf.js

+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/**
2+
sprintf() for JavaScript 0.7-beta1
3+
http://www.diveintojavascript.com/projects/javascript-sprintf
4+
5+
Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
6+
All rights reserved.
7+
8+
Redistribution and use in source and binary forms, with or without
9+
modification, are permitted provided that the following conditions are met:
10+
* Redistributions of source code must retain the above copyright
11+
notice, this list of conditions and the following disclaimer.
12+
* Redistributions in binary form must reproduce the above copyright
13+
notice, this list of conditions and the following disclaimer in the
14+
documentation and/or other materials provided with the distribution.
15+
* Neither the name of sprintf() for JavaScript nor the
16+
names of its contributors may be used to endorse or promote products
17+
derived from this software without specific prior written permission.
18+
19+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22+
DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY
23+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29+
30+
31+
Changelog:
32+
2010.09.06 - 0.7-beta1
33+
- features: vsprintf, support for named placeholders
34+
- enhancements: format cache, reduced global namespace pollution
35+
36+
2010.05.22 - 0.6:
37+
- reverted to 0.4 and fixed the bug regarding the sign of the number 0
38+
Note:
39+
Thanks to Raphael Pigulla <raph (at] n3rd [dot) org> (http://www.n3rd.org/)
40+
who warned me about a bug in 0.5, I discovered that the last update was
41+
a regress. I appologize for that.
42+
43+
2010.05.09 - 0.5:
44+
- bug fix: 0 is now preceeded with a + sign
45+
- bug fix: the sign was not at the right position on padded results (Kamal Abdali)
46+
- switched from GPL to BSD license
47+
48+
2007.10.21 - 0.4:
49+
- unit test and patch (David Baird)
50+
51+
2007.09.17 - 0.3:
52+
- bug fix: no longer throws exception on empty paramenters (Hans Pufal)
53+
54+
2007.09.11 - 0.2:
55+
- feature: added argument swapping
56+
57+
2007.04.03 - 0.1:
58+
- initial release
59+
**/
60+
61+
var sprintf = (function() {
62+
function get_type(variable) {
63+
return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
64+
}
65+
function str_repeat(input, multiplier) {
66+
for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
67+
return output.join('');
68+
}
69+
70+
var str_format = function() {
71+
if (!str_format.cache.hasOwnProperty(arguments[0])) {
72+
str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
73+
}
74+
return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
75+
};
76+
77+
str_format.format = function(parse_tree, argv) {
78+
var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
79+
for (i = 0; i < tree_length; i++) {
80+
node_type = get_type(parse_tree[i]);
81+
if (node_type === 'string') {
82+
output.push(parse_tree[i]);
83+
}
84+
else if (node_type === 'array') {
85+
match = parse_tree[i]; // convenience purposes only
86+
if (match[2]) { // keyword argument
87+
arg = argv[cursor];
88+
for (k = 0; k < match[2].length; k++) {
89+
if (!arg.hasOwnProperty(match[2][k])) {
90+
throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
91+
}
92+
arg = arg[match[2][k]];
93+
}
94+
}
95+
else if (match[1]) { // positional argument (explicit)
96+
arg = argv[match[1]];
97+
}
98+
else { // positional argument (implicit)
99+
arg = argv[cursor++];
100+
}
101+
102+
if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
103+
throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
104+
}
105+
switch (match[8]) {
106+
case 'b': arg = arg.toString(2); break;
107+
case 'c': arg = String.fromCharCode(arg); break;
108+
case 'd': arg = parseInt(arg, 10); break;
109+
case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
110+
case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
111+
case 'o': arg = arg.toString(8); break;
112+
case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
113+
case 'u': arg = Math.abs(arg); break;
114+
case 'x': arg = arg.toString(16); break;
115+
case 'X': arg = arg.toString(16).toUpperCase(); break;
116+
}
117+
arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
118+
pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
119+
pad_length = match[6] - String(arg).length;
120+
pad = match[6] ? str_repeat(pad_character, pad_length) : '';
121+
output.push(match[5] ? arg + pad : pad + arg);
122+
}
123+
}
124+
return output.join('');
125+
};
126+
127+
str_format.cache = {};
128+
129+
str_format.parse = function(fmt) {
130+
var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
131+
while (_fmt) {
132+
if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
133+
parse_tree.push(match[0]);
134+
}
135+
else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
136+
parse_tree.push('%');
137+
}
138+
else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
139+
if (match[2]) {
140+
arg_names |= 1;
141+
var field_list = [], replacement_field = match[2], field_match = [];
142+
if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
143+
field_list.push(field_match[1]);
144+
while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
145+
if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
146+
field_list.push(field_match[1]);
147+
}
148+
else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
149+
field_list.push(field_match[1]);
150+
}
151+
else {
152+
throw('[sprintf] huh?');
153+
}
154+
}
155+
}
156+
else {
157+
throw('[sprintf] huh?');
158+
}
159+
match[2] = field_list;
160+
}
161+
else {
162+
arg_names |= 2;
163+
}
164+
if (arg_names === 3) {
165+
throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
166+
}
167+
parse_tree.push(match);
168+
}
169+
else {
170+
throw('[sprintf] huh?');
171+
}
172+
_fmt = _fmt.substring(match[0].length);
173+
}
174+
return parse_tree;
175+
};
176+
177+
return str_format;
178+
})();
179+
180+
var vsprintf = function(fmt, argv) {
181+
argv.unshift(fmt);
182+
return sprintf.apply(null, argv);
183+
};

0 commit comments

Comments
 (0)