143 lines
2.7 KiB
JavaScript
143 lines
2.7 KiB
JavaScript
/*
|
|
# metrics profiler
|
|
|
|
## timing
|
|
|
|
```
|
|
var timer = Profiler.metric('resource:load')
|
|
time.start();
|
|
...
|
|
time.end();
|
|
```
|
|
|
|
## counters
|
|
|
|
```
|
|
var counter = Profiler.metric('requests')
|
|
counter.inc(); // 1
|
|
counter.inc(10); // 11
|
|
counter.dec() // 10
|
|
counter.dec(10) // 0
|
|
```
|
|
|
|
## Calls per second
|
|
```
|
|
var fps = Profiler.metric('fps')
|
|
function render() {
|
|
fps.mark();
|
|
}
|
|
```
|
|
*/
|
|
var MAX_HISTORY = 1024;
|
|
function Profiler() {}
|
|
Profiler.metrics = {};
|
|
|
|
Profiler.get = function(name) {
|
|
return Profiler.metrics[name] || {
|
|
max: 0,
|
|
min: Number.MAX_VALUE,
|
|
avg: 0,
|
|
total: 0,
|
|
count: 0,
|
|
history: typeof(Float32Array) !== 'undefined' ? new Float32Array(MAX_HISTORY) : []
|
|
};
|
|
};
|
|
|
|
Profiler.new_value = function (name, value) {
|
|
var t = Profiler.metrics[name] = Profiler.get(name);
|
|
|
|
t.max = Math.max(t.max, value);
|
|
t.min = Math.min(t.min, value);
|
|
t.total += value;
|
|
++t.count;
|
|
t.avg = t.total / t.count;
|
|
t.history[t.count%MAX_HISTORY] = value;
|
|
};
|
|
|
|
Profiler.print_stats = function () {
|
|
for (k in Profiler.metrics) {
|
|
var t = Profiler.metrics[k];
|
|
console.log(" === " + k + " === ");
|
|
console.log(" max: " + t.max);
|
|
console.log(" min: " + t.min);
|
|
console.log(" avg: " + t.avg);
|
|
console.log(" count: " + t.count);
|
|
console.log(" total: " + t.total);
|
|
}
|
|
};
|
|
|
|
function Metric(name) {
|
|
this.t0 = null;
|
|
this.name = name;
|
|
this.count = 0;
|
|
}
|
|
|
|
Metric.prototype = {
|
|
|
|
//
|
|
// start a time measurement
|
|
//
|
|
start: function() {
|
|
this.t0 = +new Date();
|
|
return this;
|
|
},
|
|
|
|
// elapsed time since start was called
|
|
_elapsed: function() {
|
|
return +new Date() - this.t0;
|
|
},
|
|
|
|
//
|
|
// finish a time measurement and register it
|
|
// ``start`` should be called first, if not this
|
|
// function does not take effect
|
|
//
|
|
end: function() {
|
|
if (this.t0 !== null) {
|
|
Profiler.new_value(this.name, this._elapsed());
|
|
this.t0 = null;
|
|
}
|
|
},
|
|
|
|
//
|
|
// increments the value
|
|
// qty: how many, default = 1
|
|
//
|
|
inc: function(qty) {
|
|
qty = qty === undefined ? 1: qty;
|
|
Profiler.new_value(this.name, Profiler.get(this.name).count + (qty ? qty: 0));
|
|
},
|
|
|
|
//
|
|
// decrements the value
|
|
// qty: how many, default = 1
|
|
//
|
|
dec: function(qty) {
|
|
qty = qty === undefined ? 1: qty;
|
|
this.inc(-qty);
|
|
},
|
|
|
|
//
|
|
// measures how many times per second this function is called
|
|
//
|
|
mark: function() {
|
|
++this.count;
|
|
if(this.t0 === null) {
|
|
this.start();
|
|
return;
|
|
}
|
|
var elapsed = this._elapsed();
|
|
if(elapsed > 1) {
|
|
Profiler.new_value(this.name, this.count);
|
|
this.count = 0;
|
|
this.start();
|
|
}
|
|
}
|
|
};
|
|
|
|
Profiler.metric = function(name) {
|
|
return new Metric(name);
|
|
};
|
|
|
|
module.exports = Profiler;
|