mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
add profile for functions, profile CSS-es on startup, use __time
This commit is contained in:
@@ -1,74 +1,100 @@
|
||||
import { assert, assertEqual, assertFalse, assertTrue, assertThrows } from "../TKUnit";
|
||||
import * as prof from "tns-core-modules/profiling";
|
||||
import { isAndroid } from "tns-core-modules/platform";
|
||||
import { enable, disable, profile, time, start, stop, pause, isRunning } from "tns-core-modules/profiling";
|
||||
|
||||
prof.enable();
|
||||
enable();
|
||||
class TestClass {
|
||||
@prof.profile("__func_decorator__")
|
||||
@profile("__func_decorator__")
|
||||
doNothing() {
|
||||
//noop
|
||||
}
|
||||
|
||||
@prof.profile("__func_decorator_error__")
|
||||
@profile("__func_decorator_error__")
|
||||
throwError() {
|
||||
throw new Error("This error is expected");
|
||||
}
|
||||
|
||||
@profile
|
||||
unnamed1() {
|
||||
// noop
|
||||
}
|
||||
|
||||
@profile()
|
||||
unnamed2() {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
const testFunction1 = profile(function testFunction1() {
|
||||
// noop
|
||||
});
|
||||
const testFunction2 = profile("testFunction2", () => {
|
||||
// noop
|
||||
});
|
||||
disable();
|
||||
|
||||
function retry(count: number, action: () => void) {
|
||||
for (var i = 1; i <= count; i++) {
|
||||
try {
|
||||
action();
|
||||
return;
|
||||
} catch(e) {
|
||||
if (i === count) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
prof.disable();
|
||||
|
||||
export function setUp() {
|
||||
prof.enable();
|
||||
enable();
|
||||
}
|
||||
|
||||
export function tearDown() {
|
||||
prof.disable();
|
||||
disable();
|
||||
}
|
||||
|
||||
export function test_time_throws_if_not_enabled() {
|
||||
prof.disable();
|
||||
assertThrows(prof.time);
|
||||
};
|
||||
|
||||
export function test_time_returns_number_if_enabled() {
|
||||
assertEqual(typeof prof.time(), "number");
|
||||
export function test_time_returns_number() {
|
||||
assertEqual(typeof time(), "number");
|
||||
};
|
||||
|
||||
export function test_isRunning() {
|
||||
const name = "test_isRunning";
|
||||
assertFalse(prof.isRunning(name), "isRunning should be false before start");
|
||||
assertFalse(isRunning(name), "isRunning should be false before start");
|
||||
|
||||
prof.start(name);
|
||||
assertTrue(prof.isRunning(name), "isRunning should be true after start");
|
||||
start(name);
|
||||
assertTrue(isRunning(name), "isRunning should be true after start");
|
||||
|
||||
prof.pause(name);
|
||||
assertFalse(prof.isRunning(name), "isRunning should be false after pause");
|
||||
pause(name);
|
||||
assertFalse(isRunning(name), "isRunning should be false after pause");
|
||||
|
||||
prof.start(name);
|
||||
assertTrue(prof.isRunning(name), "isRunning should be true after second start");
|
||||
start(name);
|
||||
assertTrue(isRunning(name), "isRunning should be true after second start");
|
||||
|
||||
prof.stop(name);
|
||||
assertFalse(prof.isRunning(name), "isRunning should be false after stop");
|
||||
stop(name);
|
||||
assertFalse(isRunning(name), "isRunning should be false after stop");
|
||||
}
|
||||
|
||||
export function test_start_stop() {
|
||||
const name = "test_start_stop";
|
||||
retry(5, () => {
|
||||
const name = "test_start_stop";
|
||||
|
||||
prof.start(name);
|
||||
const res = prof.stop(name);
|
||||
start(name);
|
||||
const res = stop(name);
|
||||
|
||||
assertEqual(res.count, 1);
|
||||
assert(res.totalTime <= 1);
|
||||
assertEqual(res.count, 1);
|
||||
assert(res.totalTime <= 1);
|
||||
});
|
||||
};
|
||||
|
||||
export function test_start_pause_count() {
|
||||
const name = "test_start_pause_count";
|
||||
|
||||
for (var i = 0; i < 10; i++) {
|
||||
prof.start(name);
|
||||
prof.pause(name);
|
||||
start(name);
|
||||
pause(name);
|
||||
}
|
||||
|
||||
const res = prof.stop(name);
|
||||
const res = stop(name);
|
||||
assertEqual(res.count, 10);
|
||||
};
|
||||
|
||||
@@ -76,52 +102,56 @@ export function test_profile_decorator_count() {
|
||||
const test = new TestClass();
|
||||
for (var i = 0; i < 10; i++) {
|
||||
test.doNothing();
|
||||
test.unnamed1();
|
||||
test.unnamed2();
|
||||
testFunction1();
|
||||
testFunction2();
|
||||
}
|
||||
|
||||
const res = prof.stop("__func_decorator__");
|
||||
assertEqual(res.count, 10);
|
||||
["__func_decorator__", "TestClass.unnamed1", "TestClass.unnamed2", "testFunction1", "testFunction2"].forEach(key => {
|
||||
const res = stop(key);
|
||||
assertEqual(res.count, 10, "Expected profile with name ${key} to have traced 10 calls.");
|
||||
});
|
||||
}
|
||||
|
||||
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");
|
||||
assertFalse(isRunning("__func_decorator_error__"), "Timer should be stopped on exception.");
|
||||
assertEqual(stop("__func_decorator_error__").count, 1, "Timer should be called once");
|
||||
}
|
||||
|
||||
export function test_start_pause_performance() {
|
||||
if (isAndroid) {
|
||||
// TODO: skip these test for android as they are unstable
|
||||
return;
|
||||
}
|
||||
retry(5, () => {
|
||||
const count = 10000;
|
||||
const name = "test_start_pause_performance";
|
||||
|
||||
const count = 10000;
|
||||
const name = "test_start_pause_performance";
|
||||
for (var i = 0; i < count; i++) {
|
||||
start(name);
|
||||
pause(name);
|
||||
}
|
||||
|
||||
for (var i = 0; i < count; i++) {
|
||||
prof.start(name);
|
||||
prof.pause(name);
|
||||
}
|
||||
|
||||
const res = prof.stop(name);
|
||||
assertEqual(res.count, count);
|
||||
assert(res.totalTime <= 50, `Total time for ${count} timer operations is too much: ${res.totalTime}`);
|
||||
const res = stop(name);
|
||||
assertEqual(res.count, count);
|
||||
assert(res.totalTime <= 500, `Total time for ${count} timer operations is too much: ${res.totalTime}`);
|
||||
});
|
||||
};
|
||||
|
||||
export function test_profile_decorator_performance() {
|
||||
if (isAndroid) {
|
||||
// TODO: skip these test for android as they are unstable
|
||||
return;
|
||||
}
|
||||
retry(5, () => {
|
||||
var start = Date.now();
|
||||
const count = 10000;
|
||||
const test = new TestClass();
|
||||
for (var i = 0; i < count; i++) {
|
||||
test.doNothing();
|
||||
}
|
||||
|
||||
const count = 10000;
|
||||
const test = new TestClass();
|
||||
for (var i = 0; i < count; i++) {
|
||||
test.doNothing();
|
||||
}
|
||||
const res = stop("__func_decorator__");
|
||||
assertEqual(res.count, count);
|
||||
|
||||
const res = prof.stop("__func_decorator__");
|
||||
assertEqual(res.count, count);
|
||||
assert(res.totalTime <= 50, `Total time for ${count} timer operations is too much: ${res.totalTime}`);
|
||||
}
|
||||
assert(res.totalTime <= 500, `Total time for ${count} timer operations is too much: ${res.totalTime}`);
|
||||
var end = Date.now();
|
||||
assert(end - start <= 1000, `Total time for test execution is too much: ${end - start}ms`);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user