зеркало из https://github.com/mozilla/pluotsorbet.git
209 строки
5.8 KiB
TypeScript
209 строки
5.8 KiB
TypeScript
|
/*
|
||
|
* Copyright 2014 Mozilla Foundation
|
||
|
*
|
||
|
* 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.
|
||
|
*/
|
||
|
|
||
|
module J2ME.Metrics {
|
||
|
export class Timer {
|
||
|
private static _base: Timer = new Timer(null, "Total");
|
||
|
private static _top = Timer._base;
|
||
|
private static _flat = new Timer(null, "Flat");
|
||
|
private static _flatStack = [];
|
||
|
private _parent: Timer;
|
||
|
private _name: string;
|
||
|
private _begin: number;
|
||
|
private _last: number;
|
||
|
private _total: number;
|
||
|
private _count: number;
|
||
|
private _timers: Map<string, Timer>;
|
||
|
constructor(parent: Timer, name: string) {
|
||
|
this._parent = parent;
|
||
|
this._timers = ObjectUtilities.createMap<string, Timer>();
|
||
|
this._name = name;
|
||
|
this._begin = 0;
|
||
|
this._last = 0;
|
||
|
this._total = 0;
|
||
|
this._count = 0;
|
||
|
}
|
||
|
public static time(name, fn: Function) {
|
||
|
Timer.start(name);
|
||
|
fn();
|
||
|
Timer.stop();
|
||
|
}
|
||
|
public static start(name) {
|
||
|
Timer._top = Timer._top._timers[name] || (Timer._top._timers[name] = new Timer(Timer._top, name));
|
||
|
Timer._top.start();
|
||
|
var tmp = Timer._flat._timers[name] || (Timer._flat._timers[name] = new Timer(Timer._flat, name));
|
||
|
tmp.start();
|
||
|
Timer._flatStack.push(tmp);
|
||
|
}
|
||
|
public static stop() {
|
||
|
Timer._top.stop();
|
||
|
Timer._top = Timer._top._parent;
|
||
|
Timer._flatStack.pop().stop();
|
||
|
}
|
||
|
public static stopStart(name) {
|
||
|
Timer.stop();
|
||
|
Timer.start(name);
|
||
|
}
|
||
|
public start() {
|
||
|
this._begin = getTicks();
|
||
|
}
|
||
|
public stop() {
|
||
|
this._last = getTicks() - this._begin;
|
||
|
this._total += this._last;
|
||
|
this._count += 1;
|
||
|
}
|
||
|
public toJSON() {
|
||
|
return {name: this._name, total: this._total, timers: this._timers};
|
||
|
}
|
||
|
public trace(writer: IndentingWriter) {
|
||
|
writer.enter (
|
||
|
this._name + ": " + this._total.toFixed(2) + " ms" +
|
||
|
", count: " + this._count +
|
||
|
", average: " + (this._total / this._count).toFixed(2) + " ms"
|
||
|
);
|
||
|
for (var name in this._timers) {
|
||
|
this._timers[name].trace(writer);
|
||
|
}
|
||
|
writer.outdent();
|
||
|
}
|
||
|
public static trace(writer: IndentingWriter) {
|
||
|
Timer._base.trace(writer);
|
||
|
Timer._flat.trace(writer);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Quick way to count named events.
|
||
|
*/
|
||
|
export class Counter {
|
||
|
public static instance: Counter = new Counter(true);
|
||
|
|
||
|
private _enabled: boolean;
|
||
|
private _counts: Map<string, number>;
|
||
|
private _times: Map<string, number>;
|
||
|
get counts(): Map<string, number> {
|
||
|
return this._counts;
|
||
|
}
|
||
|
constructor(enabled: boolean) {
|
||
|
this._enabled = enabled;
|
||
|
this.clear();
|
||
|
}
|
||
|
public setEnabled(enabled:boolean) {
|
||
|
this._enabled = enabled;
|
||
|
}
|
||
|
public clear() {
|
||
|
this._counts = ObjectUtilities.createMap<string, number>();
|
||
|
this._times = ObjectUtilities.createMap<string, number>();
|
||
|
}
|
||
|
public toJSON() {
|
||
|
return {
|
||
|
counts: this._counts,
|
||
|
times: this._times
|
||
|
};
|
||
|
}
|
||
|
public count(name: string, increment: number = 1, time: number = 0) {
|
||
|
if (!this._enabled) {
|
||
|
return;
|
||
|
}
|
||
|
if (this._counts[name] === undefined) {
|
||
|
this._counts[name] = 0;
|
||
|
this._times[name] = 0;
|
||
|
}
|
||
|
this._counts[name] += increment;
|
||
|
this._times[name] += time;
|
||
|
return this._counts[name];
|
||
|
}
|
||
|
public trace(writer: IndentingWriter) {
|
||
|
for (var name in this._counts) {
|
||
|
writer.writeLn(name + ": " + this._counts[name]);
|
||
|
}
|
||
|
}
|
||
|
private _pairToString(times, pair): string {
|
||
|
var name = pair[0];
|
||
|
var count = pair[1];
|
||
|
var time = times[name];
|
||
|
var line = name + ": " + count;
|
||
|
if (time) {
|
||
|
line += ", " + time.toFixed(4);
|
||
|
if (count > 1) {
|
||
|
line += " (" + (time / count).toFixed(4) + ")";
|
||
|
}
|
||
|
}
|
||
|
return line;
|
||
|
}
|
||
|
public toStringSorted(): string {
|
||
|
var self = this;
|
||
|
var times = this._times;
|
||
|
var pairs = [];
|
||
|
for (var name in this._counts) {
|
||
|
pairs.push([name, this._counts[name]]);
|
||
|
}
|
||
|
pairs.sort(function (a, b) {
|
||
|
return b[1] - a[1];
|
||
|
});
|
||
|
return (pairs.map(function (pair) {
|
||
|
return self._pairToString(times, pair);
|
||
|
}).join(", "));
|
||
|
}
|
||
|
public traceSorted(writer: IndentingWriter, inline = false) {
|
||
|
var self = this;
|
||
|
var times = this._times;
|
||
|
var pairs = [];
|
||
|
for (var name in this._counts) {
|
||
|
pairs.push([name, this._counts[name]]);
|
||
|
}
|
||
|
pairs.sort(function (a, b) {
|
||
|
return b[1] - a[1];
|
||
|
});
|
||
|
if (inline) {
|
||
|
writer.writeLn(pairs.map(function (pair) {
|
||
|
return self._pairToString(times, pair);
|
||
|
}).join(", "));
|
||
|
} else {
|
||
|
pairs.forEach(function (pair) {
|
||
|
writer.writeLn(self._pairToString(times, pair));
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export class Average {
|
||
|
private _samples: Float64Array;
|
||
|
private _count: number;
|
||
|
private _index: number;
|
||
|
constructor(max) {
|
||
|
this._samples = new Float64Array(max);
|
||
|
this._count = 0;
|
||
|
this._index = 0;
|
||
|
}
|
||
|
public push(sample: number) {
|
||
|
if (this._count < this._samples.length) {
|
||
|
this._count ++;
|
||
|
}
|
||
|
this._index ++;
|
||
|
this._samples[this._index % this._samples.length] = sample;
|
||
|
}
|
||
|
public average(): number {
|
||
|
var sum = 0;
|
||
|
for (var i = 0; i < this._count; i++) {
|
||
|
sum += this._samples[i];
|
||
|
}
|
||
|
return sum / this._count;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|