Skip to content

Commit 1ce3510

Browse files
author
vakrilov
committed
WIP
1 parent b127ba7 commit 1ce3510

File tree

89 files changed

+1169
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+1169
-0
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ ng-sample/lib
3535
ng-sample/node_modules
3636
ng-sample/app/nativescript-angular
3737

38+
perf-test/app/**/*.js
39+
perf-test/test-output.txt
40+
perf-test/platforms
41+
perf-test/lib
42+
perf-test/node_modules
43+
3844
startup-test/platforms
3945
startup-test/lib
4046
startup-test/node_modules
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./profiling";
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
declare var java: any;
2+
declare var CACurrentMediaTime: any;
3+
declare var __startCPUProfiler: any;
4+
declare var __stopCPUProfiler: any;
5+
6+
export let ENABLE_PROFILING = true;
7+
8+
let anyGlobal = <any>global;
9+
10+
export function time(): number {
11+
if (!ENABLE_PROFILING) {
12+
return;
13+
}
14+
15+
if (anyGlobal.android) {
16+
return java.lang.System.nanoTime() / 1000000; // 1 ms = 1000000 ns
17+
} else {
18+
return CACurrentMediaTime() * 1000;
19+
}
20+
}
21+
22+
interface TimerInfo {
23+
totalTime: number;
24+
lastTime?: number;
25+
count: number;
26+
currentStart: number;
27+
}
28+
29+
let timers = new Map<string, TimerInfo>();
30+
31+
export function start(name: string): void {
32+
if (!ENABLE_PROFILING) {
33+
return;
34+
}
35+
36+
let info: TimerInfo;
37+
if (timers.has(name)) {
38+
info = timers.get(name);
39+
if (info.currentStart !== 0) {
40+
throw new Error(`Timer already started: ${name}`);
41+
}
42+
info.currentStart = time();
43+
} else {
44+
info = {
45+
totalTime: 0,
46+
count: 0,
47+
currentStart: time()
48+
};
49+
timers.set(name, info);
50+
}
51+
}
52+
53+
export function pause(name: string) {
54+
if (!ENABLE_PROFILING) {
55+
return;
56+
}
57+
58+
let info = pauseInternal(name);
59+
console.log(`---- [${name}] PAUSE last: ${info.lastTime} total: ${info.totalTime} count: ${info.count}`);
60+
}
61+
62+
export function stop(name: string) {
63+
if (!ENABLE_PROFILING) {
64+
return;
65+
}
66+
67+
let info = pauseInternal(name);
68+
console.log(`---- [${name}] STOP total: ${info.totalTime} count:${info.count}`);
69+
70+
timers.delete(name);
71+
}
72+
73+
function pauseInternal(name: string): TimerInfo {
74+
let info = timers.get(name);
75+
if (!info) {
76+
throw new Error(`No timer started: ${name}`);
77+
}
78+
79+
info.lastTime = Math.round(time() - info.currentStart);
80+
info.totalTime += info.lastTime;
81+
info.count++;
82+
info.currentStart = 0;
83+
84+
return info;
85+
}
86+
87+
export function startCPUProfile(name: string) {
88+
if (!ENABLE_PROFILING) {
89+
return;
90+
}
91+
92+
if (anyGlobal.android) {
93+
__startCPUProfiler(name);
94+
}
95+
}
96+
97+
export function stopCPUProfile(name: string) {
98+
if (!ENABLE_PROFILING) {
99+
return;
100+
}
101+
102+
if (anyGlobal.android) {
103+
__stopCPUProfiler(name);
104+
}
105+
}
106+
107+
108+
let profileNames: string[] = [];
109+
110+
export function profileMethod(name?: string): (target, key, descriptor) => void {
111+
return (target, key, descriptor) => {
112+
// save a reference to the original method this way we keep the values currently in the
113+
// descriptor and don't overwrite what another decorator might have done to the descriptor.
114+
if (descriptor === undefined) {
115+
descriptor = Object.getOwnPropertyDescriptor(target, key);
116+
}
117+
var originalMethod = descriptor.value;
118+
119+
if (!name) {
120+
name = key;
121+
}
122+
123+
profileNames.push(name);
124+
125+
//editing the descriptor/value parameter
126+
descriptor.value = function () {
127+
// console.log("before:" + name);
128+
129+
start(name);
130+
131+
var result = originalMethod.apply(this, arguments);
132+
133+
pause(name)
134+
135+
// console.log("after:" + name);
136+
return result;
137+
};
138+
139+
// return edited descriptor as opposed to overwriting the descriptor
140+
return descriptor;
141+
}
142+
}
143+
144+
145+
export function dumpProfiles() {
146+
profileNames.forEach(function (name) {
147+
var info = timers.get(name);
148+
if (info) {
149+
console.log("---- [" + name + "] STOP total: " + info.totalTime + " count:" + info.count);
150+
}
151+
else {
152+
console.log("---- [" + name + "] Never called");
153+
}
154+
});
155+
}

nativescript-angular/renderer.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { isBlank } from "./lang-facade";
1414
import { ViewUtil } from "./view-util";
1515
import { NgView, CommentNode } from "./element-types";
1616
import { rendererLog as traceLog } from "./trace";
17+
import { profileMethod } from "./profiling";
1718

1819
// CONTENT_ATTR not exported from NativeScript_renderer - we need it for styles application.
1920
const COMPONENT_REGEX = /%COMP%/g;
@@ -82,119 +83,143 @@ export class NativeScriptRenderer extends Renderer2 {
8283
traceLog("NativeScriptRenderer created");
8384
}
8485

86+
@profileMethod()
8587
appendChild(parent: any, newChild: NgView): void {
8688
traceLog(`NativeScriptRenderer.appendChild child: ${newChild} parent: ${parent}`);
8789
this.viewUtil.insertChild(parent, newChild);
8890
}
8991

92+
@profileMethod()
9093
insertBefore(parent: NgView, newChild: NgView, refChildIndex: number): void {
9194
traceLog(`NativeScriptRenderer.insertBefore child: ${newChild} parent: ${parent}`);
9295
this.viewUtil.insertChild(parent, newChild, refChildIndex);
9396
}
9497

98+
@profileMethod()
9599
removeChild(parent: any, oldChild: NgView): void {
96100
traceLog(`NativeScriptRenderer.removeChild child: ${oldChild} parent: ${parent}`);
97101
this.viewUtil.removeChild(parent, oldChild);
98102
}
99103

104+
@profileMethod()
100105
selectRootElement(selector: string): NgView {
101106
traceLog("selectRootElement: " + selector);
102107
return this.rootView;
103108
}
104109

110+
@profileMethod()
105111
parentNode(node: NgView): any {
106112
return node.parent || node.templateParent;
107113
}
108114

115+
@profileMethod()
109116
nextSibling(node: NgView): number {
110117
traceLog(`NativeScriptRenderer.nextSibling ${node}`);
111118
return this.viewUtil.nextSiblingIndex(node);
112119
}
113120

121+
@profileMethod()
114122
createComment(_value: any): CommentNode {
115123
traceLog(`NativeScriptRenderer.createComment ${_value}`);
116124
return this.viewUtil.createComment();
117125
}
118126

127+
@profileMethod()
119128
createElement(name: any, _namespace: string): NgView {
120129
traceLog(`NativeScriptRenderer.createElement: ${name}`);
121130
return this.viewUtil.createView(name);
122131
}
123132

133+
@profileMethod()
124134
createText(_value: string): CommentNode {
125135
traceLog(`NativeScriptRenderer.createText ${_value}`);
126136
return this.viewUtil.createText();
127137
}
128138

139+
@profileMethod()
129140
createViewRoot(hostElement: NgView): NgView {
130141
traceLog(`NativeScriptRenderer.createViewRoot ${hostElement.nodeName}`);
131142
return hostElement;
132143
}
133144

145+
@profileMethod()
134146
projectNodes(parentElement: NgView, nodes: NgView[]): void {
135147
traceLog("NativeScriptRenderer.projectNodes");
136148
nodes.forEach((node) => this.viewUtil.insertChild(parentElement, node));
137149
}
138150

151+
@profileMethod()
139152
destroy() {
140153
traceLog("NativeScriptRenderer.destroy");
141154
// Seems to be called on component dispose only (router outlet)
142155
// TODO: handle this when we resolve routing and navigation.
143156
}
144157

158+
@profileMethod()
145159
setAttribute(view: NgView, name: string, value: string, namespace?: string) {
146160
traceLog(`NativeScriptRenderer.setAttribute ${view} : ${name} = ${value}, namespace: ${namespace}`);
147161
return this.viewUtil.setProperty(view, name, value, namespace);
148162
}
149163

164+
@profileMethod()
150165
removeAttribute(_el: NgView, _name: string): void {
151166
traceLog(`NativeScriptRenderer.removeAttribute ${_el}: ${_name}`);
152167
}
153168

169+
@profileMethod()
154170
setProperty(view: any, name: string, value: any) {
155171
traceLog(`NativeScriptRenderer.setProperty ${view} : ${name} = ${value}`);
156172
return this.viewUtil.setProperty(view, name, value);
157173
}
158174

175+
@profileMethod()
159176
addClass(view: NgView, name: string): void {
160177
traceLog(`NativeScriptRenderer.addClass ${name}`);
161178
this.viewUtil.addClass(view, name);
162179
}
163180

181+
@profileMethod()
164182
removeClass(view: NgView, name: string): void {
165183
traceLog(`NativeScriptRenderer.removeClass ${name}`);
166184
this.viewUtil.removeClass(view, name);
167185
}
168186

187+
@profileMethod()
169188
setStyle(view: NgView, styleName: string, value: any, _flags?: RendererStyleFlags2): void {
170189
traceLog(`NativeScriptRenderer.setStyle: ${styleName} = ${value}`);
171190
this.viewUtil.setStyle(view, styleName, value);
172191
}
173192

193+
@profileMethod()
174194
removeStyle(view: NgView, styleName: string, _flags?: RendererStyleFlags2): void {
175195
traceLog("NativeScriptRenderer.removeStyle: ${styleName}");
176196
this.viewUtil.removeStyle(view, styleName);
177197
}
178198

179199
// Used only in debug mode to serialize property changes to comment nodes,
180200
// such as <template> placeholders.
201+
@profileMethod()
181202
setBindingDebugInfo(renderElement: NgView, propertyName: string, propertyValue: string): void {
182203
traceLog("NativeScriptRenderer.setBindingDebugInfo: " + renderElement + ", " +
183204
propertyName + " = " + propertyValue);
184205
}
185206

207+
@profileMethod()
186208
setElementDebugInfo(renderElement: any, _info: any /*RenderDebugInfo*/): void {
187209
traceLog("NativeScriptRenderer.setElementDebugInfo: " + renderElement);
188210
}
189211

212+
@profileMethod()
190213
invokeElementMethod(_renderElement: NgView, methodName: string, args: Array<any>) {
191214
traceLog("NativeScriptRenderer.invokeElementMethod " + methodName + " " + args);
192215
}
193216

217+
@profileMethod()
194218
setValue(_renderNode: any, _value: string) {
195219
traceLog("NativeScriptRenderer.setValue");
196220
}
197221

222+
@profileMethod()
198223
listen(renderElement: any, eventName: string, callback: (event: any) => boolean):
199224
() => void {
200225
traceLog("NativeScriptRenderer.listen: " + eventName);
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
package="__PACKAGE__"
4+
android:versionCode="1"
5+
android:versionName="1.0">
6+
7+
<supports-screens
8+
android:smallScreens="true"
9+
android:normalScreens="true"
10+
android:largeScreens="true"
11+
android:xlargeScreens="true"/>
12+
13+
<uses-sdk
14+
android:minSdkVersion="17"
15+
android:targetSdkVersion="__APILEVEL__"/>
16+
17+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
18+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
19+
<uses-permission android:name="android.permission.INTERNET"/>
20+
21+
<application
22+
android:name="com.tns.NativeScriptApplication"
23+
android:allowBackup="true"
24+
android:icon="@drawable/icon"
25+
android:label="@string/app_name"
26+
android:theme="@style/AppTheme">
27+
28+
<activity
29+
android:name="com.tns.NativeScriptActivity"
30+
android:label="@string/title_activity_kimera"
31+
android:configChanges="keyboardHidden|orientation|screenSize"
32+
android:theme="@style/LaunchScreenTheme">
33+
34+
<meta-data android:name="SET_THEME_ON_LAUNCH" android:resource="@style/AppTheme" />
35+
36+
<intent-filter>
37+
<action android:name="android.intent.action.MAIN" />
38+
<category android:name="android.intent.category.LAUNCHER" />
39+
</intent-filter>
40+
</activity>
41+
<activity android:name="com.tns.ErrorReportActivity"/>
42+
</application>
43+
</manifest>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Add your native dependencies here:
2+
3+
// Uncomment to add recyclerview-v7 dependency
4+
//dependencies {
5+
// compile 'com.android.support:recyclerview-v7:+'
6+
//}
7+
8+
android {
9+
defaultConfig {
10+
generatedDensities = []
11+
applicationId = "org.nativescript.perftest"
12+
}
13+
aaptOptions {
14+
additionalParameters "--no-version-vectors"
15+
}
16+
}
Loading
Loading
Loading
Loading
Loading
Loading
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:gravity="fill">
2+
<item>
3+
<bitmap android:gravity="fill" android:src="@drawable/background" />
4+
</item>
5+
<item>
6+
<bitmap android:gravity="center" android:src="@drawable/logo" />
7+
</item>
8+
</layer-list>

0 commit comments

Comments
 (0)