From d95791b0a58d3330861f578ddc2f1aafec84a2c3 Mon Sep 17 00:00:00 2001 From: Panayot Cankov Date: Mon, 14 Nov 2016 11:11:09 +0200 Subject: [PATCH] Add performance tests measuring FlexboxLayout versus StackLayout and GridLayout --- .../ui-tests-app/flexbox/flexbox-main-page.ts | 1 + .../flexbox/flexbox-perf-comparison.ts | 64 +++++++++++++ .../flexbox/flexbox-perf-comparison.xml | 86 ++++++++++++++++++ apps/app/ui-tests-app/flexbox/icons/icon1.jpg | Bin 0 -> 1338 bytes apps/app/ui-tests-app/flexbox/icons/icon2.jpg | Bin 0 -> 937 bytes apps/app/ui-tests-app/flexbox/icons/icon3.jpg | Bin 0 -> 1212 bytes .../ui-tests-app/flexbox/icons/thumbsdown.png | Bin 0 -> 5129 bytes .../ui-tests-app/flexbox/icons/thumbsup.png | Bin 0 -> 5135 bytes 8 files changed, 151 insertions(+) create mode 100644 apps/app/ui-tests-app/flexbox/flexbox-perf-comparison.ts create mode 100644 apps/app/ui-tests-app/flexbox/flexbox-perf-comparison.xml create mode 100644 apps/app/ui-tests-app/flexbox/icons/icon1.jpg create mode 100644 apps/app/ui-tests-app/flexbox/icons/icon2.jpg create mode 100644 apps/app/ui-tests-app/flexbox/icons/icon3.jpg create mode 100644 apps/app/ui-tests-app/flexbox/icons/thumbsdown.png create mode 100644 apps/app/ui-tests-app/flexbox/icons/thumbsup.png diff --git a/apps/app/ui-tests-app/flexbox/flexbox-main-page.ts b/apps/app/ui-tests-app/flexbox/flexbox-main-page.ts index a0743205c..60f8f4173 100644 --- a/apps/app/ui-tests-app/flexbox/flexbox-main-page.ts +++ b/apps/app/ui-tests-app/flexbox/flexbox-main-page.ts @@ -11,6 +11,7 @@ export function pageLoaded(args: EventData) { examples.set("flexboxall", "flexbox/flexbox"); examples.set("flexrepeat", "flexbox/flexbox-repeater"); + examples.set("flex-perf", "flexbox/flexbox-perf-comparison"); let viewModel = new FlexboxMainPageViewModel(wrapLayout, examples); page.bindingContext = viewModel; diff --git a/apps/app/ui-tests-app/flexbox/flexbox-perf-comparison.ts b/apps/app/ui-tests-app/flexbox/flexbox-perf-comparison.ts new file mode 100644 index 000000000..4be7a8680 --- /dev/null +++ b/apps/app/ui-tests-app/flexbox/flexbox-perf-comparison.ts @@ -0,0 +1,64 @@ +import {TabView} from "ui/tab-view"; +import * as utils from "utils/utils"; + +const titles = ["Etiam lacinia", "Imperdiet ante", "A interdum", "Quisque tempus", "Sodales viverra"]; +const bodies = [ + "Vivamus ipsum neque, commodo rutrum finibus sit amet, cursus id sapien.", + "Duis et iaculis odio. Class aptent taciti.", + "Sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.", + "Etiam vitae lacinia purus. Vestibulum laoreet nibh a porta aliquet.", + "Vivamus ut eros vitae felis volutpat aliquet.", + "Aliquam fermentum mauris consequat hendrerit elementum.", + "Nam odio tortor, malesuada congue diam volutpat, placerat ullamcorper risus.", + "Curabitur eget nunc viverra justo bibendum rutrum ut nec lectus.", + "Pellentesque et lacus vel turpis suscipit posuere sed non sapien.", + "Integer eget ornare nunc. In lacinia congue sollicitudin.", + "Quisque lobortis quam in risus porttitor, ac laoreet lacus auctor." +]; + +const items = []; +for (var i = 0; i < 64; i++) { + items.push({ + icon: "~/ui-tests-app/flexbox/icons/icon" + (1 + (i % 3)) + ".jpg", + title: titles[i % titles.length], + body: bodies[i % bodies.length], + up: (i * 991) % 100, + down: (i * 997) % 100 + }); +} + +export function selectionChanged(args) { + clear(args); +} + +let repeaterIds = ["repeaterFlexGrid", "repeaterGrid", "repeaterFlexStack", "repeaterStack"]; + +export function clear(args) { + repeaterIds + .map(name => args.object.page.getViewById(name)) + .forEach(repeater => { + repeater.bindingContext = null; + }); + + args.object.page.getViewById("title").text = "---"; + + utils.GC(); +} + +export function generate(args) { + let tab: TabView = args.object.page.getViewById("tabview"); + let index = tab.selectedIndex; + + let repeater = args.object.page.getViewById(repeaterIds[index]); + + clear(args); + setTimeout(() => { + let start = Date.now(); + repeater.bindingContext = items; + setTimeout(() => { + let end = Date.now(); + args.object.page.getViewById("title").text = (end - start).toString(); + console.log("Duration: " + (end - start)); + }); + }); +} diff --git a/apps/app/ui-tests-app/flexbox/flexbox-perf-comparison.xml b/apps/app/ui-tests-app/flexbox/flexbox-perf-comparison.xml new file mode 100644 index 000000000..c0db01ef2 --- /dev/null +++ b/apps/app/ui-tests-app/flexbox/flexbox-perf-comparison.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/app/ui-tests-app/flexbox/icons/icon1.jpg b/apps/app/ui-tests-app/flexbox/icons/icon1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..14974904c81cfa2d73f1bc766da8408977ecb1ff GIT binary patch literal 1338 zcmex=_1P|rX?qqI0P zFI~aY%U!`Mz|~!$%*;qrN1?DZF(yimrOct*k%^gw zm5rT)lZzXuV5!ybuCbyfklv2NYT)dO*k--U8zvSsBz*#4rQl} z2StM}eo!$^Dr(~75)+q@lu}hw*U;25F*P%{u(Wb^admU|@bn4}2@MO6h>S{3Nli=7 z$jmA(DJ?6nsH|#kX>Duo=8f2KE_o9%~}YXK;@p{B?_ghnW!=dCYT}koFSa^tKW*{*<_Y${ zuFlVY*qij}?((LSXA(Z{=8As7AN4I^-j&^2Z#s8A(tUV0GH)9D<#(dDFLFx!>eJ5L z!(45}w2>pC?;W4r)>pGLw7Yb~ZTvnTlDayrJaSL>Yr(s}__A8>Of`?mYvaB?Z9d0py1<<^&NQJ~a8}I1;uE@gEEkrsJyR%Pw_Mll_F>EQOKZNLNNn`0 z*(Qo_Q%|1uoBjOfukq8CJmV)#|BUmap}8wNl*IxZiA@*Ao)` z&yew{u6b{f(I3}f!QXZ>6{lZ(@}SOn))UjS?txeH!X5`myBTzeGw^3^S4m9XwC6{E zw(!)=TPhn~d@?&w&m*;1{>aMj@(@|5@Fty#3PxJxP=EsYi@^y0_Y}YsNJ)ZO> z-v83>jY8WkmYtMmKP~g?Qr3f+k5)?UENEw~Hm_frySz1DVY2^@9sS>pJ+ecmLavy&E~4?Vh_oV16BaRBw^GU2c z=jTXoVeOyX!0z}XENrRl)xWDvigb$98KZPyc_1P|rX?qqI0P zFI~aY%U!`Mz|~!$%*;qrN1?DZF(yimrOct*k%^gw zm5rT)lZzXuV5!ybuCbyfklv2NYT)dO*k--U8zvSsBz*#4rQl} z2StM}eo!$^Dr(~75)+q@lu}hw*U;25F*P%{u(Wb^admU|@bn4}2@MO6h>S{3Nli=7 z$jmA(DJ?6nsH|#kX>Duo=8f2KE_o9%~}YXK;@p{B?_ghnW!=dCY6`WtkuQqp0P`C--qzdJlKRVi0jmMgA1 z9-LoWD>hSg@7={dNBvGN`gu^UrF6~i{I}Zj{H_vh0V!py21N_zH1~Vm-&}L+$h{T( zFT+@R7#R2N`p+;w>RD-gaH+4%_s-Jlwf=`ccCOvP`11h!g5$QV1xvbTZa;R&;ykP8 t`rsY)Mn>z3*04F+I!c%x&aR5xHaCApUHp6ox!SD9;WKYc_dD_bCIINwU7P>_ literal 0 HcmV?d00001 diff --git a/apps/app/ui-tests-app/flexbox/icons/icon3.jpg b/apps/app/ui-tests-app/flexbox/icons/icon3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d7fdca12d3ce0957b6b0d3d48a6cc79c591dc3c1 GIT binary patch literal 1212 zcmex=_1P|rX?qqI0P zFI~aY%U!`Mz|~!$%*;qrN1?DZF(yimrOct*k%^gw zm5rT)lZzXuV5!ybuCbyfklv2NYT)dO*k--U8zvSsBz*#4rQl} z2StM}eo!$^Dr(~75)+q@lu}hw*U;25F*P%{u(Wb^admU|@bn4}2@MO6h>S{3Nli=7 z$jmA(DJ?6nsH|#kX>Duo=8f2KE_o9%~}YXK;@p{B?_ghnW!=dCY-%J#&`X#3H`OeREp_ zckC37_t$FNiq(mb+^;?-G~K`QTZ1Kb-M3TQS2%L8U+Hd1B29)74Ak{!aR;awoLDn|-U` zCC{!+MT<4ozA1}pYtOHm#QaHk@=i~g$C8h4?U41lTcW)(xi4A$&YHKj zP{iw_uiQxkM|J7i)ved_Sq~ZiX$zkJHD^iP{A;^P($B13drB-C|rk<~Vrdq$ws+vF=-bCz7VtXNpS({p}025o66 zUu9O5>aco~+gbV3k#bYwO@dv!GoQ_izq{SqGxtsp*Mbi*@%K)&$*d~eqjE*-kqJ@;dZEJv8wxe`(EcI*#bYx1NOA)Chu@4P<8G-zVqd!U6zx)p0~ZY zvNFia@Ww%pC!Lq7n}qXEh{!vJ&wa literal 0 HcmV?d00001 diff --git a/apps/app/ui-tests-app/flexbox/icons/thumbsdown.png b/apps/app/ui-tests-app/flexbox/icons/thumbsdown.png new file mode 100644 index 0000000000000000000000000000000000000000..e44c04219ec55cb7f16b59ba2b0c349b172b67ca GIT binary patch literal 5129 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 literal 0 HcmV?d00001 diff --git a/apps/app/ui-tests-app/flexbox/icons/thumbsup.png b/apps/app/ui-tests-app/flexbox/icons/thumbsup.png new file mode 100644 index 0000000000000000000000000000000000000000..3a43ecae29590cb314aeeea6e1b0fc4b065df671 GIT binary patch literal 5135 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 literal 0 HcmV?d00001