mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-17 04:41:36 +08:00
Merge pull request #4180 from NativeScript/profiling-try-catch
Profiling - handle exceptions inside deocrator
This commit is contained in:
@ -14,8 +14,8 @@ const genericFontFamilies = [
|
|||||||
"serif",
|
"serif",
|
||||||
"monospace",
|
"monospace",
|
||||||
];
|
];
|
||||||
var fontFamilies = [];
|
let fontFamilies = [];
|
||||||
var fontNames = [];
|
let fontNames = [];
|
||||||
const embeddedFontNames = [
|
const embeddedFontNames = [
|
||||||
"FontAwesome",
|
"FontAwesome",
|
||||||
"Pacifico",
|
"Pacifico",
|
||||||
@ -37,21 +37,21 @@ const fontWeights = [
|
|||||||
FontWeight.black,
|
FontWeight.black,
|
||||||
];
|
];
|
||||||
|
|
||||||
var green = new Color("Green");
|
let green = new Color("Green");
|
||||||
var red = new Color("Red");
|
let red = new Color("Red");
|
||||||
var white = new Color("White");
|
let white = new Color("White");
|
||||||
var black = new Color("Black");
|
let black = new Color("Black");
|
||||||
|
|
||||||
var compareIgnoreCase = function (a, b) {
|
let compareIgnoreCase = function (a, b) {
|
||||||
return a.toLowerCase().localeCompare(b.toLowerCase());
|
return a.toLowerCase().localeCompare(b.toLowerCase());
|
||||||
};
|
};
|
||||||
|
|
||||||
if (font.ios) {
|
if (font.ios) {
|
||||||
// for (var f = 0; f < embeddedFontNames.length; f++) {
|
// for (let f = 0; f < embeddedFontNames.length; f++) {
|
||||||
// font.ios.registerFont(`fonts/${embeddedFontNames[f]}.ttf`);
|
// font.ios.registerFont(`fonts/${embeddedFontNames[f]}.ttf`);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
var font_internal = <any>font;
|
let font_internal = <any>font;
|
||||||
font_internal.ensureSystemFontSets();
|
font_internal.ensureSystemFontSets();
|
||||||
|
|
||||||
(<Set<string>>font_internal.systemFontFamilies).forEach(f => fontFamilies.push(f));
|
(<Set<string>>font_internal.systemFontFamilies).forEach(f => fontFamilies.push(f));
|
||||||
@ -62,9 +62,9 @@ if (font.ios) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function onPageLoaded(args: NavigatedData) {
|
export function onPageLoaded(args: NavigatedData) {
|
||||||
var page = <Page>args.object;
|
let page = <Page>args.object;
|
||||||
var scrollView = new ScrollView();
|
let scrollView = new ScrollView();
|
||||||
var stackLayout = new StackLayout();
|
let stackLayout = new StackLayout();
|
||||||
generateLabels(stackLayout);
|
generateLabels(stackLayout);
|
||||||
scrollView.content = stackLayout;
|
scrollView.content = stackLayout;
|
||||||
page.content = scrollView;
|
page.content = scrollView;
|
||||||
@ -72,11 +72,11 @@ export function onPageLoaded(args: NavigatedData) {
|
|||||||
|
|
||||||
function generateLabels(layout: StackLayout) {
|
function generateLabels(layout: StackLayout) {
|
||||||
layout.addChild(prepareTitle("Generic Font Families", 24));
|
layout.addChild(prepareTitle("Generic Font Families", 24));
|
||||||
for (var f = 0; f < genericFontFamilies.length; f++) {
|
for (let f = 0; f < genericFontFamilies.length; f++) {
|
||||||
layout.addChild(prepareTitle(genericFontFamilies[f], 20));
|
layout.addChild(prepareTitle(genericFontFamilies[f], 20));
|
||||||
for (var s = 0; s < fontStyles.length; s++) {
|
for (let s = 0; s < fontStyles.length; s++) {
|
||||||
for (var w = 0; w < fontWeights.length; w++) {
|
for (let w = 0; w < fontWeights.length; w++) {
|
||||||
var view = prepareLabel(genericFontFamilies[f], fontStyles[s], fontWeights[w]);
|
let view = prepareLabel(genericFontFamilies[f], fontStyles[s], fontWeights[w]);
|
||||||
layout.addChild(view);
|
layout.addChild(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,11 +86,11 @@ function generateLabels(layout: StackLayout) {
|
|||||||
{
|
{
|
||||||
layout.addChild(prepareTitle("Font Families", 24));
|
layout.addChild(prepareTitle("Font Families", 24));
|
||||||
}
|
}
|
||||||
for (var f = 0; f < fontFamilies.length; f++) {
|
for (let f = 0; f < fontFamilies.length; f++) {
|
||||||
layout.addChild(prepareTitle(fontFamilies[f], 20));
|
layout.addChild(prepareTitle(fontFamilies[f], 20));
|
||||||
for (var s = 0; s < fontStyles.length; s++) {
|
for (let s = 0; s < fontStyles.length; s++) {
|
||||||
for (var w = 0; w < fontWeights.length; w++) {
|
for (let w = 0; w < fontWeights.length; w++) {
|
||||||
var view = prepareLabel(fontFamilies[f], fontStyles[s], fontWeights[w]);
|
let view = prepareLabel(fontFamilies[f], fontStyles[s], fontWeights[w]);
|
||||||
layout.addChild(view);
|
layout.addChild(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,22 +99,22 @@ function generateLabels(layout: StackLayout) {
|
|||||||
if (fontNames.length > 0) {
|
if (fontNames.length > 0) {
|
||||||
layout.addChild(prepareTitle("Phone Fonts", 24));
|
layout.addChild(prepareTitle("Phone Fonts", 24));
|
||||||
}
|
}
|
||||||
for (var f = 0; f < fontNames.length; f++) {
|
for (let f = 0; f < fontNames.length; f++) {
|
||||||
var view = prepareLabel(fontNames[f], "normal", "normal");
|
let view = prepareLabel(fontNames[f], "normal", "normal");
|
||||||
layout.addChild(view);
|
layout.addChild(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (embeddedFontNames.length > 0) {
|
if (embeddedFontNames.length > 0) {
|
||||||
layout.addChild(prepareTitle("Embedded Fonts", 24));
|
layout.addChild(prepareTitle("Embedded Fonts", 24));
|
||||||
}
|
}
|
||||||
for (var f = 0; f < embeddedFontNames.length; f++) {
|
for (let f = 0; f < embeddedFontNames.length; f++) {
|
||||||
var view = prepareLabel(embeddedFontNames[f], "normal", "normal");
|
let view = prepareLabel(embeddedFontNames[f], "normal", "normal");
|
||||||
layout.addChild(view);
|
layout.addChild(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepareTitle(text: string, fontSize: number) {
|
function prepareTitle(text: string, fontSize: number) {
|
||||||
var title = new Label();
|
let title = new Label();
|
||||||
title.text = text;
|
title.text = text;
|
||||||
title.height = 100;
|
title.height = 100;
|
||||||
title.backgroundColor = black;
|
title.backgroundColor = black;
|
||||||
@ -128,12 +128,12 @@ function prepareTitle(text: string, fontSize: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function prepareLabel(fontFamily: string, fontStyle: string, fontWeight: string): View {
|
function prepareLabel(fontFamily: string, fontStyle: string, fontWeight: string): View {
|
||||||
var label = new Label();
|
let label = new Label();
|
||||||
label["font-family"] = fontFamily;
|
label["font-family"] = fontFamily;
|
||||||
var fontFamilyCss = `font-family: ${fontFamily}; `;
|
let fontFamilyCss = `font-family: ${fontFamily}; `;
|
||||||
var fontStyleCss = fontStyle !== FontStyle.normal ? `font-style: ${fontStyle}; ` : "";
|
let fontStyleCss = fontStyle !== FontStyle.normal ? `font-style: ${fontStyle}; ` : "";
|
||||||
var fontWeightCss = fontWeight !== FontWeight.normal ? `font-weight: ${fontWeight}; ` : "";
|
let fontWeightCss = fontWeight !== FontWeight.normal ? `font-weight: ${fontWeight}; ` : "";
|
||||||
var css = `${fontFamilyCss}${fontStyleCss}${fontWeightCss}`;
|
let css = `${fontFamilyCss}${fontStyleCss}${fontWeightCss}`;
|
||||||
label.text = `${typeUtils.getClass(label) } {${css}};`;
|
label.text = `${typeUtils.getClass(label) } {${css}};`;
|
||||||
label.textWrap = true;
|
label.textWrap = true;
|
||||||
label.style.textAlignment = "left";
|
label.style.textAlignment = "left";
|
||||||
@ -142,9 +142,9 @@ function prepareLabel(fontFamily: string, fontStyle: string, fontWeight: string)
|
|||||||
label.style.padding = "2";
|
label.style.padding = "2";
|
||||||
label.setInlineStyle(css);
|
label.setInlineStyle(css);
|
||||||
label.on("loaded", args => {
|
label.on("loaded", args => {
|
||||||
var sender = <Label>args.object;
|
let sender = <Label>args.object;
|
||||||
if (sender.ios) {
|
if (sender.ios) {
|
||||||
var uiFont = _getUIFont(label);
|
let uiFont = _getUIFont(label);
|
||||||
sender.text += `\niOS Font: ${uiFont.fontName};`;
|
sender.text += `\niOS Font: ${uiFont.fontName};`;
|
||||||
if (genericFontFamilies.indexOf(fontFamily) !== -1) {
|
if (genericFontFamilies.indexOf(fontFamily) !== -1) {
|
||||||
return;
|
return;
|
||||||
|
@ -2,21 +2,21 @@
|
|||||||
import * as gestures from "tns-core-modules/ui/gestures";
|
import * as gestures from "tns-core-modules/ui/gestures";
|
||||||
|
|
||||||
export function onTouch(args: gestures.TouchGestureEventData) {
|
export function onTouch(args: gestures.TouchGestureEventData) {
|
||||||
var msg = " touch action: " + args.action +
|
let msg = " touch action: " + args.action +
|
||||||
" x: " + Math.round(args.getX()) + " y: " + Math.round(args.getY()) +
|
" x: " + Math.round(args.getX()) + " y: " + Math.round(args.getY()) +
|
||||||
" count: " + args.getPointerCount();
|
" count: " + args.getPointerCount();
|
||||||
|
|
||||||
var p;
|
let p;
|
||||||
msg += " ACTIVE: ";
|
msg += " ACTIVE: ";
|
||||||
var pointers = args.getActivePointers();
|
let pointers = args.getActivePointers();
|
||||||
for (var index = 0; index < pointers.length; index++) {
|
for (let index = 0; index < pointers.length; index++) {
|
||||||
p = pointers[index];
|
p = pointers[index];
|
||||||
msg += " p" + index + "[" + Math.round(p.getX()) + ", " + Math.round(p.getY()) + "]"
|
msg += " p" + index + "[" + Math.round(p.getX()) + ", " + Math.round(p.getY()) + "]"
|
||||||
}
|
}
|
||||||
|
|
||||||
msg += " ALL: ";
|
msg += " ALL: ";
|
||||||
pointers = args.getAllPointers();
|
pointers = args.getAllPointers();
|
||||||
for (var index = 0; index < pointers.length; index++) {
|
for (let index = 0; index < pointers.length; index++) {
|
||||||
p = pointers[index];
|
p = pointers[index];
|
||||||
msg += " p" + index + "[" + Math.round(p.getX()) + ", " + Math.round(p.getY()) + "]"
|
msg += " p" + index + "[" + Math.round(p.getX()) + ", " + Math.round(p.getY()) + "]"
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,20 @@
|
|||||||
import * as TKUnit from "../TKUnit";
|
import { assert, assertEqual, assertFalse, assertTrue, assertThrows } from "../TKUnit";
|
||||||
import * as prof from "tns-core-modules/profiling";
|
import * as prof from "tns-core-modules/profiling";
|
||||||
|
|
||||||
|
prof.enable();
|
||||||
|
class TestClass {
|
||||||
|
@prof.profile("__func_decorator__")
|
||||||
|
doNothing() {
|
||||||
|
//noop
|
||||||
|
}
|
||||||
|
|
||||||
|
@prof.profile("__func_decorator_error__")
|
||||||
|
throwError() {
|
||||||
|
throw new Error("This error is expected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prof.disable();
|
||||||
|
|
||||||
export function setUp() {
|
export function setUp() {
|
||||||
prof.enable();
|
prof.enable();
|
||||||
}
|
}
|
||||||
@ -11,56 +25,93 @@ export function tearDown() {
|
|||||||
|
|
||||||
export function test_time_throws_if_not_enabled() {
|
export function test_time_throws_if_not_enabled() {
|
||||||
prof.disable();
|
prof.disable();
|
||||||
TKUnit.assertThrows(prof.time);
|
assertThrows(prof.time);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function test_time_returns_number_if_enabled() {
|
export function test_time_returns_number_if_enabled() {
|
||||||
TKUnit.assertEqual(typeof prof.time(), "number");
|
assertEqual(typeof prof.time(), "number");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function test_isRunning() {
|
||||||
|
const name = "test_isRunning";
|
||||||
|
assertFalse(prof.isRunning(name), "isRunning should be false before start");
|
||||||
|
|
||||||
|
prof.start(name);
|
||||||
|
assertTrue(prof.isRunning(name), "isRunning should be true after start");
|
||||||
|
|
||||||
|
prof.pause(name);
|
||||||
|
assertFalse(prof.isRunning(name), "isRunning should be false after pause");
|
||||||
|
|
||||||
|
prof.start(name);
|
||||||
|
assertTrue(prof.isRunning(name), "isRunning should be true after second start");
|
||||||
|
|
||||||
|
prof.stop(name);
|
||||||
|
assertFalse(prof.isRunning(name), "isRunning should be false after stop");
|
||||||
|
}
|
||||||
|
|
||||||
export function test_start_stop() {
|
export function test_start_stop() {
|
||||||
prof.start("__test1__");
|
const name = "test_start_stop";
|
||||||
const res = prof.stop("__test1__");
|
|
||||||
|
|
||||||
TKUnit.assertEqual(res.count, 1);
|
prof.start(name);
|
||||||
TKUnit.assert(res.totalTime <= 1);
|
const res = prof.stop(name);
|
||||||
|
|
||||||
|
assertEqual(res.count, 1);
|
||||||
|
assert(res.totalTime <= 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function test_start_pause() {
|
export function test_start_pause_count() {
|
||||||
|
const name = "test_start_pause_count";
|
||||||
|
|
||||||
for (var i = 0; i < 10; i++) {
|
for (var i = 0; i < 10; i++) {
|
||||||
prof.start("__test2__");
|
prof.start(name);
|
||||||
prof.pause("__test2__");
|
prof.pause(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = prof.stop("__test2__");
|
const res = prof.stop(name);
|
||||||
TKUnit.assertEqual(res.count, 10);
|
assertEqual(res.count, 10);
|
||||||
TKUnit.assert(res.totalTime <= 1);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function test_timer_performance() {
|
export function test_start_pause_performance() {
|
||||||
for (var i = 0; i < 10000; i++) {
|
const count = 1000;
|
||||||
prof.start("__test3__");
|
const name = "test_start_pause_performance";
|
||||||
prof.pause("__test3__");
|
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
prof.start(name);
|
||||||
|
prof.pause(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = prof.stop("__test3__");
|
const res = prof.stop(name);
|
||||||
TKUnit.assertEqual(res.count, 10000);
|
assertEqual(res.count, count);
|
||||||
TKUnit.assert(res.totalTime <= 30, "Total time for 1000 timer operations is too much: " + res.totalTime);
|
assert(res.totalTime <= 50, `Total time for ${count} timer operations is too much: ${res.totalTime}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function test_profile_decorator_count_counts() {
|
export function test_profile_decorator_count() {
|
||||||
class TestClass {
|
const test = new TestClass();
|
||||||
@prof.profile("__func_decorator__")
|
for (var i = 0; i < 10; i++) {
|
||||||
f() {
|
test.doNothing();
|
||||||
//noop
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const res = prof.stop("__func_decorator__");
|
||||||
|
assertEqual(res.count, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function test_profile_decorator_performance() {
|
||||||
|
const count = 1000;
|
||||||
|
|
||||||
const test = new TestClass();
|
const test = new TestClass();
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
for (var i = 0; i < 10; i++) {
|
test.doNothing();
|
||||||
test.f();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = prof.stop("__func_decorator__");
|
const res = prof.stop("__func_decorator__");
|
||||||
TKUnit.assertEqual(res.count, 10);
|
assertEqual(res.count, count);
|
||||||
|
assert(res.totalTime <= 50, `Total time for ${count} timer operations is too much: ${res.totalTime}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function test_profile_decorator_handles_exceptions() {
|
||||||
|
const test = new TestClass();
|
||||||
|
|
||||||
|
assertThrows(() => test.throwError());
|
||||||
|
assertFalse(prof.isRunning("__func_decorator_error__"), "Timer should be stopped on exception.");
|
||||||
|
assertEqual(prof.stop("__func_decorator_error__").count, 1, "Timer should be called once");
|
||||||
}
|
}
|
@ -2,4 +2,6 @@
|
|||||||
import { Border } from "tns-core-modules/ui/border";
|
import { Border } from "tns-core-modules/ui/border";
|
||||||
// << border-require
|
// << border-require
|
||||||
|
|
||||||
console.dir(Border);
|
if (Border) {
|
||||||
|
// NOOP
|
||||||
|
}
|
7
tns-core-modules/profiling/profiling.d.ts
vendored
7
tns-core-modules/profiling/profiling.d.ts
vendored
@ -48,6 +48,13 @@ export declare function pause(name: string): TimerInfo;
|
|||||||
*/
|
*/
|
||||||
export declare function stop(name: string): TimerInfo;
|
export declare function stop(name: string): TimerInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if a timer is currently running.
|
||||||
|
* @param name Name of the timer.
|
||||||
|
* @returns true is the timer is currently running.
|
||||||
|
*/
|
||||||
|
export declare function isRunning(name: string): boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method decorator factory. It will intercept the method call and start and pause a timer before and after the method call.
|
* Method decorator factory. It will intercept the method call and start and pause a timer before and after the method call.
|
||||||
* Works only if profiling is enabled.
|
* Works only if profiling is enabled.
|
||||||
|
@ -11,11 +11,13 @@ interface TimerInfo extends TimerInfoDefinition {
|
|||||||
isRunning: boolean;
|
isRunning: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
let anyGlobal = <any>global;
|
// Use object instead of map as it is a bit faster
|
||||||
|
const timers: { [ index: string ]: TimerInfo } = {};
|
||||||
|
const anyGlobal = <any>global;
|
||||||
|
const profileNames: string[] = [];
|
||||||
|
|
||||||
let ENABLED = true;
|
let ENABLED = true;
|
||||||
let nativeTimeFunc: () => number;
|
let nativeTimeFunc: () => number;
|
||||||
let profileNames: string[] = [];
|
|
||||||
let timers = new Map<string, TimerInfo>();
|
|
||||||
|
|
||||||
export function enable() {
|
export function enable() {
|
||||||
ENABLED = true;
|
ENABLED = true;
|
||||||
@ -49,7 +51,8 @@ export function start(name: string): void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let info = timers.get(name);
|
let info = timers[ name ];
|
||||||
|
|
||||||
if (info) {
|
if (info) {
|
||||||
if (info.isRunning) {
|
if (info.isRunning) {
|
||||||
throw new Error(`Timer already running: ${name}`);
|
throw new Error(`Timer already running: ${name}`);
|
||||||
@ -63,7 +66,7 @@ export function start(name: string): void {
|
|||||||
currentStart: time(),
|
currentStart: time(),
|
||||||
isRunning: true
|
isRunning: true
|
||||||
};
|
};
|
||||||
timers.set(name, info);
|
timers[ name ] = info;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,18 +88,24 @@ export function stop(name: string): TimerInfo {
|
|||||||
let info = pauseInternal(name);
|
let info = pauseInternal(name);
|
||||||
console.log(`---- [${name}] STOP total: ${info.totalTime} count:${info.count}`);
|
console.log(`---- [${name}] STOP total: ${info.totalTime} count:${info.count}`);
|
||||||
|
|
||||||
timers.delete(name);
|
timers[ name ] = undefined;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isRunning(name: string): boolean {
|
||||||
|
const info = timers[ name ];
|
||||||
|
return !!(info && info.isRunning);
|
||||||
|
}
|
||||||
|
|
||||||
function pauseInternal(name: string): TimerInfo {
|
function pauseInternal(name: string): TimerInfo {
|
||||||
let info = timers.get(name);
|
const info = timers[ name ];
|
||||||
|
|
||||||
if (!info) {
|
if (!info) {
|
||||||
throw new Error(`No timer started: ${name}`);
|
throw new Error(`No timer started: ${name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.isRunning) {
|
if (info.isRunning) {
|
||||||
info.lastTime = Math.round(time() - info.currentStart);
|
info.lastTime = time() - info.currentStart;
|
||||||
info.totalTime += info.lastTime;
|
info.totalTime += info.lastTime;
|
||||||
info.count++;
|
info.count++;
|
||||||
info.currentStart = 0;
|
info.currentStart = 0;
|
||||||
@ -120,7 +129,12 @@ export function profile(name?: string): MethodDecorator {
|
|||||||
var originalMethod = descriptor.value;
|
var originalMethod = descriptor.value;
|
||||||
|
|
||||||
if (!name) {
|
if (!name) {
|
||||||
name = key;
|
let className = "";
|
||||||
|
if (target && target.constructor && target.constructor.name) {
|
||||||
|
className = target.constructor.name + ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
name = className + key;
|
||||||
}
|
}
|
||||||
|
|
||||||
profileNames.push(name);
|
profileNames.push(name);
|
||||||
@ -128,12 +142,11 @@ export function profile(name?: string): MethodDecorator {
|
|||||||
//editing the descriptor/value parameter
|
//editing the descriptor/value parameter
|
||||||
descriptor.value = function () {
|
descriptor.value = function () {
|
||||||
start(name);
|
start(name);
|
||||||
|
try {
|
||||||
var result = originalMethod.apply(this, arguments);
|
return originalMethod.apply(this, arguments);
|
||||||
|
} finally {
|
||||||
pause(name)
|
pause(name);
|
||||||
|
}
|
||||||
return result;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// return edited descriptor as opposed to overwriting the descriptor
|
// return edited descriptor as opposed to overwriting the descriptor
|
||||||
@ -143,7 +156,8 @@ export function profile(name?: string): MethodDecorator {
|
|||||||
|
|
||||||
export function dumpProfiles(): void {
|
export function dumpProfiles(): void {
|
||||||
profileNames.forEach(function (name) {
|
profileNames.forEach(function (name) {
|
||||||
let info = timers.get(name);
|
const info = timers[ name ];
|
||||||
|
|
||||||
if (info) {
|
if (info) {
|
||||||
console.log("---- [" + name + "] STOP total: " + info.totalTime + " count:" + info.count);
|
console.log("---- [" + name + "] STOP total: " + info.totalTime + " count:" + info.count);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user