import { time } from 'tns-core-modules/profiling'; import { ActionBar } from 'tns-core-modules/ui/action-bar'; import { ActivityIndicator } from 'tns-core-modules/ui/activity-indicator'; import { Border } from 'tns-core-modules/ui/border'; import { Button } from 'tns-core-modules/ui/button'; import { ContentView } from 'tns-core-modules/ui/content-view'; import { DatePicker } from 'tns-core-modules/ui/date-picker'; import { HtmlView } from 'tns-core-modules/ui/html-view'; import { Image } from 'tns-core-modules/ui/image'; import { Label } from 'tns-core-modules/ui/label'; import { AbsoluteLayout } from 'tns-core-modules/ui/layouts/absolute-layout'; import { DockLayout } from 'tns-core-modules/ui/layouts/dock-layout'; import { FlexboxLayout } from 'tns-core-modules/ui/layouts/flexbox-layout'; import { GridLayout } from 'tns-core-modules/ui/layouts/grid-layout'; import { StackLayout } from 'tns-core-modules/ui/layouts/stack-layout'; import { WrapLayout } from 'tns-core-modules/ui/layouts/wrap-layout'; import { ListPicker } from 'tns-core-modules/ui/list-picker'; import { ListView } from 'tns-core-modules/ui/list-view'; import { Page } from 'tns-core-modules/ui/page'; import { Progress } from 'tns-core-modules/ui/progress'; import { Repeater } from 'tns-core-modules/ui/repeater'; import { SegmentedBar } from 'tns-core-modules/ui/segmented-bar'; import { Switch } from 'tns-core-modules/ui/switch'; import { TabView } from 'tns-core-modules/ui/tab-view'; import { TextField } from 'tns-core-modules/ui/text-field'; import { TextView } from 'tns-core-modules/ui/text-view'; import { TimePicker } from 'tns-core-modules/ui/time-picker'; import { View } from 'tns-core-modules/ui/core/view'; import { FormattedString, Span } from 'tns-core-modules/text/formatted-string'; import { _getProperties, _getStyleProperties } from 'tns-core-modules/ui/core/properties'; declare var __startCPUProfiler; declare var __stopCPUProfiler; const count = 200; export function testSetup(layout: StackLayout): string { setupSetters(); return ''; } export function testFlexboxLayout(layout: StackLayout): string { return test(layout, () => new FlexboxLayout(), count); } export function testDockLayout(layout: StackLayout): string { return test(layout, () => new DockLayout(), count); } export function testGridLayout(layout: StackLayout): string { return test(layout, () => new GridLayout(), count); } export function testStackLayout(layout: StackLayout): string { return test(layout, () => new StackLayout(), count); } export function testWrapLayout(layout: StackLayout): string { return test(layout, () => new WrapLayout(), count); } export function testAbsoluteLayout(layout: StackLayout): string { return test(layout, () => new AbsoluteLayout(), count); } export function testButton(layout: StackLayout): string { return test(layout, () => new Button(), count); } export function testActionBar(layout: StackLayout): string { return test(layout, () => new ActionBar(), count); } export function testActivityIndicator(layout: StackLayout): string { return test(layout, () => new ActivityIndicator(), count); } export function testBorder(layout: StackLayout): string { return test(layout, () => new Border(), count); } export function testContentView(layout: StackLayout): string { return test(layout, () => new ContentView(), count); } export function testDatePicker(layout: StackLayout): string { return test(layout, () => new DatePicker(), count); } export function testHtmlView(layout: StackLayout): string { return test(layout, () => new HtmlView(), count); } export function testImage(layout: StackLayout): string { return test(layout, () => new Image(), count); } export function testLabel(layout: StackLayout): string { return test(layout, () => new Label(), count); } export function testListPicker(layout: StackLayout): string { return test(layout, () => new ListPicker(), count); } export function testListView(layout: StackLayout): string { return test(layout, () => new ListView(), count); } export function testPage(layout: StackLayout): string { return test(layout, () => new Page(), count); } export function testProgress(layout: StackLayout): string { return test(layout, () => new Progress(), count); } export function testRepeater(layout: StackLayout): string { return test(layout, () => new Repeater(), count); } export function testSwitch(layout: StackLayout): string { return test(layout, () => new Switch(), count); } export function testTextField(layout: StackLayout): string { return test(layout, () => new TextField(), count); } export function testTextView(layout: StackLayout): string { return test(layout, () => new TextView(), count); } function test(layout: StackLayout, createView: () => View, count: number): string { const viewMap1 = new Map(); const cssMap1 = new Map(); viewMap1.set('isEnabled', false); let result = execute(layout, createView, count, viewMap1, cssMap1) viewMap1.set('text', 'text'); viewMap1.set('automationText', "automationText"); cssMap1.set('width', 100); cssMap1.set('height', 100); cssMap1.set('rotate', '90'); result += execute(layout, createView, count, viewMap1, cssMap1) viewMap1.set('clipToBounds', false); viewMap1.set('left', '20'); viewMap1.set('top', '20'); viewMap1.set('dock', 'top'); viewMap1.set('stretchLastChild', false); cssMap1.set('paddingLeft', '30px'); cssMap1.set('paddingTop', '30px'); cssMap1.set('paddingRight', '30px'); cssMap1.set('paddingBottom', '30px'); cssMap1.set('horizontalAlignment', 'center'); cssMap1.set('verticalAlignment', 'center'); result += execute(layout, createView, count, viewMap1, cssMap1) viewMap1.set('row', '1'); viewMap1.set('rowSpan', '2'); viewMap1.set('col', '1'); viewMap1.set('colSpan', '2'); cssMap1.set('rotate', '90'); cssMap1.set('scaleX', 2); cssMap1.set('scaleY', 2); cssMap1.set('translateX', 20); cssMap1.set('translateY', 20); cssMap1.set('clipPath', 'inset(100px 50px)'); cssMap1.set('color', 'red'); cssMap1.set('tintColor', 'green'); cssMap1.set('placeholderColor', 'green'); cssMap1.set('backgroundColor', 'red'); cssMap1.set('backgroundImage', '~/logo.png'); result += execute(layout, createView, count, viewMap1, cssMap1) result += execute(layout, createView, count, setters, cssSetters); return `${createView().typeName}: ${result}`; } let b = false; function execute(layout: StackLayout, createView: () => View, count: number, viewProps: Map, cssProps: Map): string { gc(); java.lang.System.gc(); gc(); java.lang.System.gc(); // b = !b; // let not: { time: number, count: number }; let recycled: { time: number, count: number }; // if (b) { // not = profile(layout, createView, count, false, viewProps, cssProps); // recycled = profile(layout, createView, count, true, viewProps, cssProps); // } else { recycled = profile(layout, createView, count, true, viewProps, cssProps); // not = profile(layout, createView, count, false, viewProps, cssProps); // } // console.log(`recycled: ${recycled.time}`); // console.log(`not: ${not.time}`); // const improved = ((not.time - recycled.time) / not.time) * 100; const propCount = recycled.count; return `\t${recycled.time.toFixed(0)}`; } const props = _getProperties(); const styleProps = _getStyleProperties(); function profile(layout: StackLayout, createView: () => View, count: number, recycle: boolean, viewProps: Map, cssProps: Map): { time: number, count: number } { const view = createView(); view.recycleNativeView = recycle ? 'always' : 'never'; const style = view.style; // DatePicker throws OOM const c = view.typeName === 'DatePicker' ? 1 : 5; let total = 0; let x = 0; for (let i = 0; i < c; i++) { x = 0; viewProps.forEach((v, k) => { const p = props.find(vp => (vp).name === k); // if (p && view[p.setNative]) { view[k] = v; x++; // } }); cssProps.forEach((v, k) => { const p = styleProps.find(vp => (vp).name === k); // if (p && view[p.setNative]) { style[k] = v; x++; // } }); const start = time(); for (let i = 0; i < count; i++) { layout.addChild(view); layout.removeChild(view); } const end = time() - start; total += end; } return { time: total / c, count: x }; } let setters: Map; let cssSetters: Map; function setupSetters(): void { if (setters) { return; } setters = new Map(); // view-base setters.set('id', "someId"); setters.set('className', "someClassName"); setters.set('bindingContext', "someBindingContext"); // view setters.set('automationText', "automationText"); setters.set('originX', 0.2); setters.set('originY', 0.2); setters.set('isEnabled', false); setters.set('isUserInteractionEnabled', false); // action-bar setters.set('title', 'title'); setters.set('text', 'text'); setters.set('icon', '~/logo.png'); setters.set('visibility', 'collapse'); // activity-indicator setters.set('busy', true); // date-picker setters.set('year', '2010'); setters.set('month', '2'); setters.set('day', '2'); setters.set('maxDate', '2100'); setters.set('minDate', '2000'); setters.set('date', new Date(2011, 3, 3)); // editable-text setters.set('keyboardType', 'datetime'); setters.set('returnKeyType', 'done'); setters.set('editable', false); setters.set('updateTextTrigger', 'focusLost'); setters.set('autocapitalizationType', 'words'); setters.set('autocorrect', true); setters.set('hint', 'hint'); setters.set('maxLength', '10'); // html-view setters.set('html', ''); // image-view setters.set('imageSource', ''); setters.set('src', ''); setters.set('loadMode', 'async'); setters.set('isLoading', true); setters.set('stretch', 'none'); // layout-base setters.set('clipToBounds', false); // absolute-layout setters.set('left', '20'); setters.set('top', '20'); // dock-layout setters.set('dock', 'top'); setters.set('stretchLastChild', false); // grid-layout props setters.set('row', '1'); setters.set('rowSpan', '2'); setters.set('col', '1'); setters.set('colSpan', '2'); // stack-layout setters.set('orientation', 'horizontal'); // wrap-layout // custom orientation value // setters.set('orientation', 'vertical'); setters.set('itemWidth', '50'); setters.set('itemHeight', '50'); // list-picker setters.set('items', ['1', '2', '3']); setters.set('selectedIndex', '1'); // list-view setters.set('items', ['1', '2', '3']); setters.set('itemTemplate', '