3 var manual = 0; // single stepping
4 var interval_time = 0; // setTimeout interval
5 var inner_loop_enabled = 1; // should the stepper iterate a little during each step
9 var query = window.location.search.substring(1);
10 var params = query.split('&');
11 for (var i = 0; i < params.length; i++) {
12 var pos = params[i].indexOf('=');
13 var key = params[i].substring(0, pos);
14 var val = params[i].substring(pos+1);
16 var sz = parseInt(val);
17 size = Math.max(sz, 3);
18 size = Math.min(1000, size);
24 if (window.console != undefined) {
25 window.console.log(msg);
29 function Sort(name, func) {
33 this.compare_x = null;
34 this.compare_y = null;
41 this.work_queue = new Array();
44 this.num_iterations = 0;
46 this.overhead_total = 0;
47 this.overhead_min = 1000000;
48 this.overhead_max = 0;
49 this.processing_total = 0;
50 this.processing_min = 1000000;
51 this.processing_max = 0;
52 this.step_min = 1000000;
58 Sort.prototype.setup = function() {
60 this.bars = new Array(this.size);
61 this.numbers = new Array(this.size);
62 for (i = 0; i < this.size; i++) {
63 this.numbers[i] = i + 1;
65 for (i = 0; i < this.size; i++) {
66 var r = Math.floor(Math.random() * this.numbers.length);
68 var tmp = this.numbers[i];
69 this.numbers[i] = this.numbers[r];
70 this.numbers[r] = tmp;
75 Sort.prototype.status = function(str) {
76 var label = document.getElementById(this.name + "_label");
77 label.innerHTML = "<b>" + this.name + " Sort</b><br />" + str;
80 Sort.prototype.stepper = function() {
83 this.timer = setTimeout(function(){sort.stepper();},interval_time);
86 var overhead = t - this.last_time;
87 this.overhead_total += overhead;
88 this.overhead_min = Math.min(this.overhead_min, overhead);
89 this.overhead_max = Math.max(this.overhead_max, overhead);
92 var elapsed = t - this.start_time;
94 Math.floor((elapsed - this.processing_total) / this.num_iterations);
95 this.status("Overhead: " + avg + "ms");
99 var count = this.work_queue.length;
101 var func = this.work_queue.pop();
102 if (func.status != undefined) {
103 //this.status(func.status);
111 if (manual || inner_loop_enabled == 0) {
115 // If any measurable time has passed, we're good.
116 // Since the Date has a resolution of 15ms on Windows
117 // there's no way to differentiate accurately for anything
118 // less than that. We don't want to process for longer than
119 // the timer interval anyway (which is about 10ms), so this
121 // NOTE: on non-windows platforms, this actually does matter since
122 // their timer resolution is higher
123 // TODO(erikkay): make this a parameter
124 if (t - this.last_time > 10) {
128 var processing = t - this.last_time;
129 this.processing_min = Math.min(this.processing_min, processing);
130 this.processing_max = Math.max(this.processing_max, processing);
131 this.processing_total += processing;
132 var step_time = processing + overhead;
133 this.step_min = Math.min(this.step_min, step_time);
134 this.step_max = Math.max(this.processing_max, step_time);
135 this.num_iterations++;
136 this.last_time = new Date();
143 Sort.prototype.add_work = function(work, name) {
144 if (name != undefined) {
147 this.work_queue.push(work);
150 Sort.prototype.init = function() {
155 Sort.prototype.reset = function() {
163 Sort.prototype.start = function() {
164 if (this.start_time > 0) {
165 if (this.stop_time > 0) {
181 this.timer = setTimeout(function(){t.stepper();},interval_time);
185 this.start_time = (new Date()).getTime();
186 this.last_time = this.start_time;
189 this.overhead_total = 0;
190 this.overhead_min = 1000000;
191 this.overhead_max = 0;
192 this.processing_total = 0;
193 this.processing_min = 1000000;
194 this.processing_max = 0;
195 this.num_iterations = 0;
199 Sort.prototype.cleanup = function() {
200 if (this.compare_x) {
201 this.compare_x.style.borderColor = "black";
202 this.compare_y.style.borderColor = "black";
205 this.swap_x.style.backgroundColor = "green";
206 this.swap_y.style.backgroundColor = "green";
208 this.work_queue = new Array();
211 Sort.prototype.stop = function() {
212 if (this.timer != 0) {
213 clearTimeout(this.timer);
219 Sort.prototype.finished = function(err) {
222 this.stop_time = (new Date()).getTime();
224 var total = (this.stop_time - this.start_time);
226 var step_avg = Math.floor(total / this.num_iterations);
227 var overhead = total - this.processing_total;
228 var overhead_avg = Math.floor(overhead / this.num_iterations);
229 var processing_avg = Math.floor(this.processing_total / this.num_iterations);
230 var table = "<table><tr><td>Times(ms)</td><td>Total</td><td>Avg</td><td>Max</td></tr>"
231 + "<tr><td>Total</td><td>" + total + "</td><td>" + step_avg + "</td><td>" + this.step_max + "</tr>"
232 + "<tr><td>Work</td><td>" + this.processing_total + "</td><td>" + processing_avg + "</td><td>" + this.processing_max + "</tr>"
233 + "<tr><td>Overhead</td><td>" + overhead + "</td><td>" + overhead_avg + "</td><td>" + this.overhead_max + "</tr>"
238 log("error: " + err);
240 log("finished in: " + total);
243 Sort.prototype.shuffle = function() {
244 for (i = 0; i < this.size; i++) {
245 var r = Math.floor(Math.random() * this.size);
253 Sort.prototype.print = function() {
254 var graph = document.getElementById(this.name);
255 if (graph == undefined) {
256 alert("can't find " + this.name);
258 var text = "<div id='" + this.name + "_label' class='label'>" + this.name + " Sort</div>";
259 var len = this.numbers.length;
260 var height_multiple = (graph.clientHeight-20) / len;
261 var width = Math.max(1,Math.floor((graph.clientWidth-10) / len));
267 var left_offset = Math.round((graph.clientWidth - (width*len))/2);
268 for (i = 0; i < len; i++) {
269 var val = this.numbers[i];
270 var height = Math.max(1, Math.floor(val * height_multiple));
271 var left = left_offset + i * width;
272 text += "<li class='bar' style='border: " + border + "px solid black; height:" + height + "px; left:" + left + "; width:" + width + "' id='" + this.name + val + "' value='" + val + "'></li>";
274 graph.innerHTML = text;
275 var nodes = document.getElementsByTagName("li");
277 for (i = 0; i < nodes.length; i++) {
278 var name = nodes[i].id;
279 if (name.indexOf(this.name) == 0) {
280 this.bars[j] = nodes[i];
286 Sort.prototype.compare = function(x, y) {
287 var bx = this.bars[x];
288 var by = this.bars[y];
289 //log("compare " + x + "(" + bx.value + ")," + y + "(" + by.value + ")");
290 if (this.compare_x != bx) {
291 if (this.compare_x) {
292 this.compare_x.style.borderColor="black";
294 bx.style.borderColor="yellow";
297 if (this.compare_y != by) {
298 if (this.compare_y) {
299 this.compare_y.style.borderColor="black";
301 by.style.borderColor="white";
305 return bx.value - by.value;
308 Sort.prototype.swap = function(x, y) {
309 var bx = this.bars[x];
310 var by = this.bars[y];
311 //log("swap " + x + "(" + bx.value + ")," + y + "(" + by.value + ")");
312 if (this.swap_x != x) {
314 this.swap_x.style.backgroundColor="green";
316 bx.style.backgroundColor="blue";
319 if (this.swap_y != y) {
321 this.swap_y.style.backgroundColor="green";
323 by.style.backgroundColor="red";
326 var tmp = bx.style.left;
327 bx.style.left = by.style.left;
334 Sort.prototype.insert = function(from, to) {
335 var bf = this.bars[from];
337 for (i = from; i > to; i--) {
338 var b1 = this.bars[i];
339 var b2 = this.bars[i-1];
340 b2.style.left = b1.style.left;
343 bf.style.left = this.bars[to].style.left;