summaryrefslogtreecommitdiffstats
path: root/trunk/infrastructure/ace/www/profiler.js
blob: 24b68a23ce588cf31b266b088d50a1102f88ecd6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/**
 * Copyright 2009 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// author: David Greenspan
// a basic profiler
// e.g. var p = PROFILER("somename", true);
//      p.mark("abc"); abc();
//      p.mark("xyz"); var x = xyz();
//      p.literal(x, "someNumber");
//      p.end();

// Note that IE/Win only has 16 ms time resolution for each run.

var _profilersByName = {};
function PROFILER(name, enabled) {
  if (!_profilersByName['$'+name]) {
    _profilersByName['$'+name] = _makeProfiler(name, enabled);
  }
  var p = _profilersByName['$'+name];
  p.start();
  return p;
}

function resetProfiler(name) {
  delete _profilersByName['$'+name];
}

function _makeProfiler(name, enabled) {
  enabled = (enabled !== false);

  var _profileTime;
  var _profileResults;
  var _profileTotal;
  var _profileHistory = [];
  var running = false;

  function profileStart(name) {
    _profileResults = [];
    _profileTotal = 0;
    if (name) _profileResults.push(name);
    running = true;
    _profileTime = (new Date()).getTime();
  }

  function profileMark(name) {
    var stopTime = (new Date()).getTime();
    var dt = stopTime - _profileTime;
    _profileResults.push(dt);
    _profileTotal += dt;
    if (name) _profileResults.push(name);
    _profileTime = (new Date()).getTime();
  }

  function profileLiteral(value, name) {
    _profileResults.push(value);
    if (name) _profileResults.push("%="+name);
  }

  function profileEnd(name) {
    if (running == false) return;
    var stopTime = (new Date()).getTime();
    var dt = stopTime - _profileTime;
    _profileResults.push(dt);
    _profileTotal += dt;
    if (name) _profileResults.push(name);
    _profileResults.unshift(_profileTotal,"=");
    _profileHistory.push(_profileResults);
    if (dumpProfileDataTimeout)
      top.clearTimeout(dumpProfileDataTimeout);
    dumpProfileDataTimeout = top.setTimeout(dumpProfileData, 800);
    running = false;
  }

  var dumpProfileDataTimeout = null;

  function dumpProfileData() {
    var data = _profileHistory[0].slice();
    forEach(_profileHistory.slice(1), function (h) {
      forEach(h, function (x, i) {
	if ((typeof x) == "number") data[i] += x;
      });
    });
    data = map(data, function (x) {
      if ((typeof x) == "number") return String(x/_profileHistory.length).substring(0,4);
      return x;
    });
    data.push("("+_profileHistory.length+")");
    top.pad.dmesg(data.join(" ").replace(/ %/g,''));
    dumpProfileDataTimeout = null;
  }

  function noop() {}
  function cancel() {
    running = false;
  }

  if (enabled) {
    return {start:profileStart, mark:profileMark, literal:profileLiteral, end:profileEnd,
	    cancel:cancel};
  }
  else {
    return {start:noop, mark:noop, literal:noop, end:noop, cancel:noop};
  }
}