From 40db84e6537a3af10a0060ad1a101bef83bc8fdc Mon Sep 17 00:00:00 2001 From: shirakaba <14055146+shirakaba@users.noreply.github.com> Date: Sat, 17 Dec 2022 17:46:31 +0900 Subject: [PATCH] feat: profiling setup --- apps/new/src/plugin-demos/properties.ts | 12 ++++++ apps/old/src/plugin-demos/properties.ts | 49 +++++++++++++++++++++++++ packages/core/profiling/jamie.ts | 37 +++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 packages/core/profiling/jamie.ts diff --git a/apps/new/src/plugin-demos/properties.ts b/apps/new/src/plugin-demos/properties.ts index 69fd3f8e4..9592743f7 100644 --- a/apps/new/src/plugin-demos/properties.ts +++ b/apps/new/src/plugin-demos/properties.ts @@ -1,4 +1,5 @@ import { Button, EventData, Page, Switch, View, getViewById, Observable, Label, PropertyChangeData } from '@nativescript/core'; +import { jamieProfiler } from '@nativescript/core/profiling/jamie'; export function navigatingTo(args: EventData) { const page = args.object; @@ -47,11 +48,22 @@ export class DemoModel extends Observable { this.target.addEventListener(Observable.propertyChangeEvent, onPropertyChange, null); + jamieProfiler.flush(); + + console.log('BEGIN PROFILE'); const time = profile(() => { for (let i = 0; i < 1000000; i++) { this.target.setProperty(propName, i); } }); + console.log('END PROFILE'); + + console.log( + jamieProfiler + .report(jamieProfiler.flush()) + .map(([key, value]) => `${key}: ${value} ms`) + .join('\n') + ); this.target.removeEventListener(Observable.propertyChangeEvent, onPropertyChange, null); diff --git a/apps/old/src/plugin-demos/properties.ts b/apps/old/src/plugin-demos/properties.ts index 69fd3f8e4..bab2d1c9e 100644 --- a/apps/old/src/plugin-demos/properties.ts +++ b/apps/old/src/plugin-demos/properties.ts @@ -1,5 +1,43 @@ import { Button, EventData, Page, Switch, View, getViewById, Observable, Label, PropertyChangeData } from '@nativescript/core'; +class Profiler { + private map: Record = {}; + + profile(key: string, action: () => T) { + const start = global.isIOS ? (global as any).performance.now() : __time(); + const returnValue = action(); + const stop = global.isIOS ? (global as any).performance.now() : __time(); + const period = stop - start; + + this.map[key] = (this.map[key] || 0) + period; + + // console.log(`[PROFILE] ${key}: ${stop - start} ms`); + return returnValue; + } + + flush() { + const map = this.map; + this.map = {}; + return map; + } + + get(key: string) { + return this.map[key]; + } + + report(map: Record = this.map) { + return Object.entries(map).sort(([, valueA], [, valueB]) => { + return sortDescending(valueA, valueB); + }); + } +} + +function sortDescending(a: number, b: number): 1 | 0 | -1 { + return a < b ? 1 : a > b ? -1 : 0; +} + +const jamieProfiler = new Profiler(); + export function navigatingTo(args: EventData) { const page = args.object; @@ -47,11 +85,22 @@ export class DemoModel extends Observable { this.target.addEventListener(Observable.propertyChangeEvent, onPropertyChange, null); + jamieProfiler.flush(); + + console.log('BEGIN PROFILE'); const time = profile(() => { for (let i = 0; i < 1000000; i++) { this.target.setProperty(propName, i); } }); + console.log('END PROFILE'); + + console.log( + jamieProfiler + .report(jamieProfiler.flush()) + .map(([key, value]) => `${key}: ${value} ms`) + .join('\n') + ); this.target.removeEventListener(Observable.propertyChangeEvent, onPropertyChange, null); diff --git a/packages/core/profiling/jamie.ts b/packages/core/profiling/jamie.ts new file mode 100644 index 000000000..4c4d0c7c7 --- /dev/null +++ b/packages/core/profiling/jamie.ts @@ -0,0 +1,37 @@ +class Profiler { + private map: Record = {}; + + profile(key: string, action: () => T) { + const start = global.isIOS ? (global as any).performance.now() : __time(); + const returnValue = action(); + const stop = global.isIOS ? (global as any).performance.now() : __time(); + const period = stop - start; + + this.map[key] = (this.map[key] || 0) + period; + + // console.log(`[PROFILE] ${key}: ${stop - start} ms`); + return returnValue; + } + + flush() { + const map = this.map; + this.map = {}; + return map; + } + + get(key: string) { + return this.map[key]; + } + + report(map: Record = this.map) { + return Object.entries(map).sort(([, valueA], [, valueB]) => { + return sortDescending(valueA, valueB); + }); + } +} + +function sortDescending(a: number, b: number): 1 | 0 | -1 { + return a < b ? 1 : a > b ? -1 : 0; +} + +export const jamieProfiler = new Profiler();