From 88950fd90bebb9d3ea4ef76292c66aa8d9f3bfae Mon Sep 17 00:00:00 2001 From: John Kerl Date: Sat, 20 Jun 2026 10:39:43 -0400 Subject: [PATCH] Add PNG graphics to perf docs for issue-2084 perf mods (#2095) * perf how-to * PNG files to docs --- docs/src/perf/timings-2026-06-20-cats.png | Bin 0 -> 35064 bytes docs/src/perf/timings-2026-06-20-chains.png | Bin 0 -> 35958 bytes docs/src/perf/timings-2026-06-20-verbs.png | Bin 0 -> 40555 bytes docs/src/performance.md | 4 + docs/src/performance.md.in | 4 + scripts/perf/README.md | 78 ++++++++++++++++++++ scripts/perf/plot-timings.sh | 30 ++++++++ scripts/perf/run-perf.sh | 22 ++++++ scripts/perf/time-verbs.py | 11 ++- scripts/perf/timings-2026-06-20.dat | 36 +++++++++ 10 files changed, 181 insertions(+), 4 deletions(-) create mode 100644 docs/src/perf/timings-2026-06-20-cats.png create mode 100644 docs/src/perf/timings-2026-06-20-chains.png create mode 100644 docs/src/perf/timings-2026-06-20-verbs.png create mode 100644 scripts/perf/README.md create mode 100755 scripts/perf/plot-timings.sh create mode 100755 scripts/perf/run-perf.sh create mode 100644 scripts/perf/timings-2026-06-20.dat diff --git a/docs/src/perf/timings-2026-06-20-cats.png b/docs/src/perf/timings-2026-06-20-cats.png new file mode 100644 index 0000000000000000000000000000000000000000..660ba041109c0010618b94e9c6c058fb8302a39e GIT binary patch literal 35064 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 Jv9$TS{{m<=+Lr(T literal 0 HcmV?d00001 diff --git a/docs/src/perf/timings-2026-06-20-chains.png b/docs/src/perf/timings-2026-06-20-chains.png new file mode 100644 index 0000000000000000000000000000000000000000..3d719d3d00757e6a37224bcc24cc3423ef73f006 GIT binary patch literal 35958 zcmce;WmHt{+c%7ggaRTcT~bO*4JDzpFd(ILcOxYYf^>JIG*ZIQDT?&aozgLcbi;EF zm;dX&@3ro=-sj8nesGP7d(Yly9KSkFgWkwVV&5aVhk}BFEiEOch=Ov*4+Z76Dh3+( z8~$IF;;IfxHpULldhd-;pn49rmNpKSX8Kf4M(^#-Y^*t1*`KrWGEKTnt>1;x6isq}%Gwnx&0L!BxlRl^Y{f>SJHm4tErtw{io=Mn}JneX7f< zDGPqqK|tm6P4v~PBf(SQ9h((dV-C(vKiZg{)SXqAUi%+ONt{o82KHAxymm-O1_uYJ z!Q-HyOa*Ok-M{(W0nY7L$lrWp_`m&>w9!FcpzF*}lDhkwS5-kl!B~I@6$~AU2wQ$Z zK~#A;M?rpmWLulW6;3}LPJpPQk`f&Y3lt9@-`7)1`F?XS^7>a_8yYm7wx>Jg$p!UK z{>%@S>NI~&m+{91Kf|yy?!Skoq^M~4-TPK_WF*zVK*jO*7Bg$>_{m9i1{RjMuCCYn zJ4_G=BwzN)tta3T+*j)K=68M7)YQ-$kM4h4W5Yj~Q+oftd~>|)C+erO9p*&uNF7n+ z7eC3iK#Ma*!$ccMJD7{Ps^7bC9({Q8@>F6K9swgF65V1x+s2pmgI*>r6(LWkP{Bp7 zTKCb?xP8|!)2~Y~Fm565b1Uiz@+T-M)Hna)KcBb|;~ZY22GNyt(h^umB2IsnJp$wxL{T zOuEzAdS3UP2QR27Jr1IZwCdl!3c|X1-}(5*n+es;a}45-52KSvp2FyjIx7a&8$HxK zCi}mL!U^t0yx0poM+mwdNj>}LQK^;HpuU<{t2yr{G7`Gx5^NIgB94qoeT-xSRL7n95xb&F!sKG&Pwy zjeDN^Z2kCjAMWz=*3F{t4={cHp+k`J)8?h;*}@)cqvy<}iIk$|*pGWGjm(UU9CWG8 zSBIq@6k{TV#ocVp)8trR6BCJQFOR06BKbMl=@JnXR#jE>&}74M_Xk2JpD`D>n23w` z>{n`hUvk_27O6d&w16LKB<~cWFRHfO?q`2W~D;y`oxiglzcIQI0 z-l1`3Kvp7*n3H~O%+Sc_lx%2)qwC%gvw+iPqA*5{ye=!p z_PJ6{#tkB*bwqBK&%u*A@U3)-8_@+cAMatX37U&lH|XTMl(27h^m$#`<6~{`i(8>( z<)o7|h)YVQNIXwY+O(ue)Sc7uZAsAaoIoTx@ozERdZHx(HnulLwmq83l3~SpszIA! zheDRC7sY(wLz*5TVd3VfJ}ng$BMBKSiWjQdZd=@(ra~+%aPt1g73SXIv$8{|(Ej zCZZ#N(({>3^JNwBqtg95jvekM{E=0T?c~mhC7+W$hMD#B^)tzwr|ni6nBJAd&gN>p z;TAbm*3sEMpX3dP5)H zeDDA3PYhC+Nnd<^{VgF~h^kd}nJ}%V46T z{r&wZJiH_$(#es}kK1n$AxM9-&4fU0mcqv%c>K6CQ#{1*bZ>bN6y6R=N)K9TY3V`y zj(^aB^nu_(WRXs@b}lr9UXX#0PtCgV@a;sMV_}hIt>P6ZUmbZFo{Yj5e|$s9_!OJ2 z&MaJh`=GmSUSj^mk}skGU4EGOuFRY!$X&lYA3zCd$;h)?Z0o!}_qy(LzdUZfZfu{; zxY^!;4jP0(4Q^Q-b8ODr_X%ZmDm>1eYIoa6>3DeF0r;j96x7OK#K7nawrjHHTz%B5OQ$`6^Y zBi47lu9TO$P6wx6zka=x8N$jjQ3>W$*}8U_ASm1#uEnBOF6NI-x^kHOG{aqS)_osZ z`}^blo{W^_#OsbzLDSZee51*4yE?)V7Te?8%|eJmIr0n;$mZC zKbM}yz0-~wDSVe=U%0TKpTut9k7-HBs%hFgr7~%xoaS|PI;ix|BJv0_PS_}{YqGjx zwta3ov6mxtWuoPlVcp?xww~iOI*iw=bA2|Z-ST-*#G?Q6OYL?CS>MMuFae|JW28IG zUL>1D^EDsLmZt9pwSuJ8u`QL)e!Ar|39s#EO}DK|&$(;e3$PSp@7^bny1u$xu5P|8 zK6u1&LkM*S->~cn&rW=!IP5AaX}k*8qPFYQ;{Svu^m^>~UBtnV{4rmy#ehM+u2mBH%0lMsQ)w0{`bfh#95w{cJ6 zXPub1xMh3Ul7JiMQX6N z*uc@TvF;&xVXIMrBibAK_n9pS`rde^ZsT$;(EYkPJi~dZIVAPabgZPBu!4ojs_*|A zOb!WgttZNV8B)l|$Ute*NUdvLx{~~Z*a>S=zO3=OBrzoztW>E7L)$LRtVHbkewO3k zUheJhFG~uaDO9J|fBo7O8c+1%!?y;2z{bU2@;*XlWa_6HT=siLAF^-?ZdDBRXm^Wy z9oNrEKl{53#U|PVL;0I7S3`wf(z^K{R4K^|j%;#kjLkS$ird@6h#w3he4>&=~1PSqM!!x3SzufgKc=)q)mE*TwI>Vrc=%ZFn+Jfbs>^q(P0d>i>$ z*}1tAND`dFV*}y5GZmhW;s0~~IRb5`VP7tZ&ptQlLHy>ltC!0xntpR~;Y zVvsl}xpCOya-z?3<=CYqHjM)7=B2*lEN9gn>izGi#EJU)S|q@ICjRMf(5Or(f6v%tS_6IoACj z-4PZRhUCg!6DAofe0+QW;2AM7F*&TKd26@p5ZT|peUqH~r|6@&N?TbKPdm?f>@6qg zbOG(KjO6Y}I=_KHEI;r%@kR3Xa{XVy6mDKO!--kW^k((X$5t34+)@J4Bd_&KGM`_pZ92KmJw$hf;V7#bQT z?)Cf?Gm>E>M&X5o+83ijT?sFw~1eN zi$C{}jhHL{L$J=&bhg2SuW9ysw7;JUu&9#GR5N4QloC_SoIHS4DZ1b4>ePGr5zH}g zx9iK}Wj}nmNTA<72s*D1=Fs;~*Vtu+QVMGu!;_7UD7`MqF!5G<)27xDjfbNe%V&sE zo}KeW%4=11b@e4st6-_lvo0%$l0o|y7k_>#s;JOCO>>CGvB`FThY5DPHh+)1eii*^PS`Ja2C4zv~yzgeImU3{g*f#Hs zrsJ?2e_lFf%CP+ZLgEM@Kuw8hbURMA%ug2(7S^GcOEu+)`b!GdM7fAwoQ-6O9(j&2 z*W}8S>Kw%wML$Xz&apTBuB5DN_?p-25}|YcqQvK|2H^O$0z}H{>MrM7)hXU@WTXYd zCP_1j~yN5RN-RBN;pRm!hFt!qQFv*QkVcK?3>UCK- zXR*VIibORO*O8BR@Aqi`ZwR)4BxE6kY>wFNgKoebp-Csm|tg=Fe4lPa*?MvPWp`xN|OYZaG?k3D+E0B-|FGiNx;7y8;V= zG`E}RnV7m)6Cnu-Z@-yLlo{K1#u>6X^&U9ovn9yyV7kt2Lm|Ufr=H|L>rAR?gOB z8-E#2%$Y0MEC1KK@U**J`oyUn>0;6w6Vj$d`!tNVb5loX-^gB*atDc@oO=JeR#S2< zP-_e|OuXC|}CWUfSvjZv8p=%l-a85@d}IS;M7elr*&3jaG? z{{A!n6S{7yshJ9N!Yo(XK#~v1v|~KLO3@|mnq+{KX1$p^c@~(*+cOqzaxVZ)9@J<$ zT_LRnhC|P>`%;u-@^8n!biqAfpro9Jo~I{T#b%Pdh_H zsmaq->A~TGiv#d9{VZ}XcEyHHmZKyoqCoZPHp%cXu5;SJ5+diAi;M0Q*sl5MaCc-g z%NP?MAAh-KF`RQ%tMdh)ex><1rJcaNDcQT8txep55{f!A~$m!5ijp zraAkbtv?bxtQfYQe#U~0eZhrv0iM57B1X-|HvFj2=w55dx8oiZ91?S4w@5o58H6XS z_mNgM_1SLiA{{+lQU(WdG|<7<{1FZh4gKuN&wdB}wG1?j>z#`9)?}rzeMoS0O%x5C z=Yp7YKh?lvW_}J%I!4Ce3?bx&As84BBg5l)|C}Mnul&l>T@~@3LZki31+twk(F(Mh zylRaR4Pn-dVb$u;6?e_qnhc!eLth);$~{`o4k>fG38P4YSA4XlCQjez$~bx7%n(! z8NZTDQZQA~DUgy6H8VHQHXdPw)rw2XOs@?HO^6AyfjfAYJfRY+cUW^jYDnn8xVOds zl~@?NZIG3BE{%AT8Gb@X;aM}m%mRff>eRrAsay^5xnoo_GHj~$j%O_{0|Y*N!^9JW z1(m6(;r+6G2X07Z3TCd!-C<*x;@oU~vgIUoz&Hlh2Wbb$mtB_M!6Z^N6g~9g6%10Q zSPiyp1`R*oMA}Q)MBWy6tJiXi3$B}W$Vs-95D65LsgG>KAu+6q#h0_CwE0>TT^Ht} zZGn$~SaWH~Su|aaT3X`-v_=pwra@DAU+NDIx~`@mcjFoE?N@%}X%>lGF6H3qv9T4a zjY2p@G^=MFct^a;YKvqy_V#+{cN!KwJvYDU^(qjRSZ1PyhU@(#`UJilMFR|qSYU7% zH~DKv8G)UK(dZ#TH(A}aBWAz~R=|=zLlq!4sE|f|Y3kDYM=;j)4w8BuzJfa1jkV2EO$+9iHM(q1>)Q!3Om>UQs23yJKa(I!2%loln$adps?23U}b%b=nXO=aQR z6gUh2q#@3fF+MplapOMrEfnv-cb9M;#iMO^v+3r!Y5VLnFYSolL?P9wYMTV4_@DJS z)&kr-f|ia>T23xJ)or`>{XU#WrrGndA^jRjxf_pXndaR0!%mH^cH1d!w7oi>1bh(O z0Xziwzoi|(!eyKIrsvD&{Q7k;nd7j+UZKuq7piVc$rCbe^VmlO1j***fRMgS_dGL$ zt+0WprC0dc-Q{FHAjj+a3jOeM&S3}&LKqq_fDK4}{K^OGNk4WbJ|69^q%cQHPELXJ zMzxiFiKJ$8i{QPif*RG0`}ca@UR|9RQ?~WU1_>MLTR`j<#Dd7#Uu9-yoeF^Uk1n3F zzEv|XQJU+r@f}erGdLhAGs-ESa&^z6<(-ZP9k345F=zcBP_lBG^v2fI@Zx_r>(6T$ z1!%GEd3ABRf8&r9DCKpjnWWLpd0jU)0NTde6c6YJ8 zJCvByaH`5`4~$U?^iDlU2;UYc`!uB z&##Unu=#xdB$`gfaQvH|cB#u==hJ04&s^+%)|&4ZwFL#zto555_OhIoB&up$7{m6m z8A3A%vN@0Av{d)KPWtl?>p2O@MS9=37Hj_F`&-_IVq0C}CDo5}zE$1Rr(19niYERKuTIRRRs= z>lg%~Re!Z9Lnf=h`qz!Pxw}|sGkt1x%8Z08(b>{5IAiwHXzgDika3o%eje%tS; zA$6SsJ9Qa5M37-M>y0RAD7jFm0uf+?#Mo&2^zxV!=T_Gfef0-tyG+e-`Ptd5X+M); z&T#HA)JqaLbyZwSip5dA^UjfrEN5Vb=UD->cEk7!>oCXhzowFKZvFGP&@1ty3okHJghE=ZGMHF>wT?Pqg}PP372)Sr-g%!TP3G1GmTeZa`|W zJv1tRd|dki8S%QObmp@gw4q*Rb#`^_@x>=6n;%)3oUFSx0KP5xwpjh~A9rMqab|&e zbjf{w3hWLyL3vnEgy2yk7X;Gfb+zi1OwV<;ItxM#zlSXCf#e*mmIY7KmV{=N73Mds zHwGGVL3uZ0WlPvt?uM@jNm>@QhLIx7wHNQ^(AiigkMAPKQXF&1Az>P^}l$Inng2>2tG!8$0 z^dT%BX6mQw1UCZN#`tvqn}iDow4I2D_=@pgB&ecQeji|Dt4 z^#&G!qkm>R>^1-Z=qlERY0wc#H!U=SRa)s)wKjVs(kw%@N-o~Fd^AMf)zy^^(iyBI z8&WI?7gvYIOH{a^c)KoYm#jJDPj-x4w2~a(ug13Wr?&6V$2WPx?bOta@gr^(h2`WZ zCL}zqL~w~XpoJuBSu(Q3ef=fV1E$Npp>=h|)dasiV&`y<8B|c6|H-KigD6wt9X4u$ zKtk|6G^U@b17=^)`*8Typ)VTt#zE~NH$RuQK*C1Rccd*cbK|+igiYr6wE?Fo(BM0Y zooohcCk4zU8L^RVy-4ruZCZWOo(QuaX?t|!g@XJ2G$v4+u z_ZZw(wal0q9!k2_Woy}b{&z>tcO5u#IJslQe*7O_qBq*yMCY z8{!<8Y2zoPu_&aeqT-;S)D<8}ozP|0a2vzq|5O$v&1)ATKv^W=WLwSHwUg&E2o7ZmhXAZjhnpPn2ra$2Z?SUJSi^B3v(Mf! zsv$nH3R21^wqW0$gz^Z*TPn|DVh_-@vB~vv&NPm#Rub9Le-s7qvFl`IM3usYdo8!G ziB#Un%(R73OtfMfr)9>cj=CSGO-$?S(+ZhXv|7*)Bq#9dePl4Y3*e#;EYg0OicZ-D zAhFy7Vv|RS0ue&1WdRNLR-s)_d85kq%Q@LVK|$^k*A;GrC15SaJvW^z z0p7SGrGxQav)un@Q?ZQ z&yJ7p;d1MSk_t}7g58KRj_oXh@}qgl;lvh}lkWQU{KJsX9mV=5eJaR3i`d(T?{3h^ zAPb&m>far-`r6_Bdo~ZG6!`K|1cQp&jQ+XH*?=*OYixwCKFQh?PH+A#pN7MHtcX2D zLpiq9$mHA*pFAn)hOtqv5GKXv=F+d=W=^d)GkIOl-Ud^pONv~tAI85J!z#FVWPToP zZLe_m9tM%ht}2m7ebM-ZPFa^h$!Yt!&?StU%`UUmC?YmLG4X~P%!}FdFD@?Tl$6MI zb$5fTE329f^P$AG7Q>}8fh_QgGw<8t65t39yWrP5ZB5QLJ)&CR-k#fG=Bz9aLX62= z##e#&?TJ?UF`L!N!7@Vi_Zv6j<>D<7%4WjAfMvL~ zii(OhqDjR6k8W#gs}$(R>EuNaY&L!>zVicQ!f%C6m+;k^+-oO5Bam6R^O0m`^Nb5{ zK8*lDEC+2I_7u=_%J&^l_F^(F!~k{R4+;z0+B?Ll>ljn~fOCsot!OPw)r&*iSTMh^zPm%h!um&@hg5dbR_ znRQtu&sa>mjGA^F)7ty(`yjd5k0#=U;(L4hocw$#kZ%~8yF>_V^PYkp4_XF>0+}%x zfY8;sU5o`&i6-Siy>>*Tpx#QDnVJ6acn?4sNJVqqMN93h^F+@}*TunGC>RXeZldj@ zS`sEbiBCW_QiEji#-xC}WB%rsQG$U$rcl%C@{r^GlGO1oGzHQL(ql$sufvN!-|y@R zU+)XgT#%z+JY{F-jJ}bZBv_-5EzM$}(^POHBgH%ec8FzUd9_C0mwf_gZ9ylk9M`QZ zgS9uWV=s=*g;tna}+HAVMn9S`D{P9)AL8+ybBnxxk`(7HahpbpMP0i zE&J)8#Bvy`G~J#8aMMXNoioL>OO8iM%d?43yV0Ql=&-;L&MdYUupnTWK;!X1&3Gj; z{`20wd(-wJD4&@CiFH5Vf~h4V5ILUv#u=9S_9}71C0Z6$91-@d#u2f8K>-!U_>PYx zjOpp}K*@M?OYeajFzR})KoGyPUVU3vbTWu*K2r2A*pLgT-w^{m*ltIAXkEEF_<^v4 zurNK%PbQIJOMOkJDzRU!2ZPR_O27KV?I&2{|0lxhBJ0NN^nC*SR;Hi+*a&5~gU0FU zDTi?nk$uSCcm&7#2;h}hn$G;+Ggj4EG8Pzo+cVhw(ZCSs?&hI!hANxWfiu54?zavgw00pUiEsgiH`XEaQUg^YACNjLK zCCNWuTVH!3*?r%n0k<4+tAAfTIXSz@HpSwR1cEm-_wxKwXpY@95@r@A31N3?#Rv)x zUn#whV*928*B^)Yhjnfiot*Hc13uQQ+fL&Q0oIYf&9Uc{_4EArEj4~ zj`CY~f}aZXwnZCJ@Q@Pp8Jwl+c8RNi*1CqXjlx?Qgx0sd^b!vb;E_8LA6h<(AxU5i zFeWpvs=^tji2M=!3ZIG~p0JJwo2roHtD(uV9E@e6u@&LSuE5Um!l(xG(Tv)!VM`cg z@(X4COyYEGzd}&MXX~$Qxkm5v_-*o5MF|K=wBT9oBh%0ulyi7o0Eg(d*yc@X6{vieuvy3y(oY z(AW@8Q9Q%4b?KHc;&|TB0 zU(dzGgX(VeO7^3?0qMSDbCfZhX5tRj1$TVBYeI_oos^F(>gDtM)A@d=L1UF+fFWQK z+1u0c2N}OZ=^w)doBx&`(Y)_`aY3!L)4MGv^pJD}LFGY3!LMWg{%Eq4&7tu&MrmkB z-d!Qw-ee1loSRCeubp0@{O(+c59yt0q>Pd2e-xLLu!UBlpa}W`Sb0K)MdSYbV_wov zt+@JzF~+(s1@1u0sP9?gTvQcZa#JN5hHcci>Bt)8IR!ECuIa6%2OOB|@#AxkCK}Em zP}aQ_#uz2UmHcr~zI^wvSp!e{P>5(ItE52ANqO^+nPrw6i@abWamd-Kn4~_B))VhH zX3UK5(E<>aL+h^i%%g+^8=2x6tLA0}X6lQ;ZlL6Oo4L4ndjF2Mb=$x96D+O!GFb#Y zz``qrj>%WGCzqK*-uXunhlre*m3)n!3?pp>6q}UiwTxEUPK<$mk9%v?L~G*Jr5j)Y zRQk4ar2HW3^Lrq%Q*O-c3aQ#nEhCbeA`VF>mM~_%J^v-AOktzinj3+1yP@bfCmu}( z<8Mryl_D(lH~;8y!ESp~+5LNuxn(|s0dvbmJ_B}K$yibUJe*@j!OAuhENPM-q2iw- zB7T@o*H>4%gfXRzfAgqEGNjyO6a`7$R(V@Ew5KyFzosTqM*!u(ar*f0v_AB_4Oboh zZ0B}*^w|XYfCHDmvs(;FyoJ6NWM)>@7ZkccXL8}x*i8oSGxZJVtfy6-Ap@vE>hF`2 zCz$}>^0<54_(fENNa93SjG&J=WV=W|l9Qm)Ck!p5M-}yl=zn(#G!^ELPs?Z|fX&AJ zCiPi(%LO%tx5vL@Og!IXRBQof>8&$I#nmXN<#grL&b|Q}maP$P+Hx)l z?FQDbX8|-wx+fU+?_&DQWnTl+&yy!q#wHNpG#J;i*gW5&!9SJ&{uq_coYb$BzA zi~AISwUG9Ly?rArsJ0d_Ep;0C9y6c*y-|M*CjloO2jCM-st%44Ms3vn^*~|w@Qd|X zW|k;fmXsWMyjPCxB&&iWrS)c*47#`PkAIiUS}$>kMt4=6?=M|r<|-@8EU(_z@aP&M ze%jlOUvg^INUE&tUc+KqB|~ zpB9mbUho_*D@mqQiQA5hnI$B}yZe{EfZ;uhY+KL=R~~L#>i>5|@!YdPKx9~#-E*2Z zNKR@k&H^3f{=d`onFkDWiAqINiS>a}$>?mT_&WwhP6D5PWQ#=@DUgf^IRCHsI{vw* z?X6Poy{7MK%`6}T?7ApkRw%Fh|7)1WOqkV)+jLECUQ)-x#avlgS*n@vd$>9YX-?C( ze(u{pUWx*yiOW;R{jm-KSjGSfmkvqa_KDL>sW2i`CqpG+oIGERxi1yv2K&lWX1 z*yOi=JpX}yCkkR9?zcU9R(i5Z7%G;fNt>9=qBCH27aLqM#etdBfs8x^N6)WI)c#FOrQ#J4afRvv+Q=}497 z*d8k0cNh$2z*P>pz^x`0dg$xApxi0rn%m6}RV?4eOL~6@JXP<0(|LC1512*=42+*r zrS8woaRM8hK6Q+ix>J%mHgp(yJ(k|2tV8$|n=o%oiuJMP)7vsL#d>ffCs(#}y+o^b zg}dbaP~9OSM{kU^xi4aUPG`YU4mlQRA-jBhc+0ka7n8RRSWx|LcA@LCFZ&MJb<1a? z15E07y$@y%QOJ8#9ZVkkrk3&Yntgi*LDsHg3w~P>bDkv^?$UzpK0>oSmWN}90lT%e zy(kJ}fWh(#y~~V=IW4?p>G${1JA{cog@|jP*|qo8Z-_>15`U?o{@l$;AXuM?CSWj7 zNNV0}NgU77XBIQ$Dc#yOf2aH{=z~nI>| zLWfU{e~UQplUQkH!SEN$C0`>$QEZV!8Y(R0LcrU5&^E_L*y+~1Um7CwkeIiZm`eTS z!uMV3^(=Ayj;~Y~#>~mq`6UCyJ}36F{j41p%dwNQ3skSOC}Z;^g8^FFE0 zcL*neV{vBT{jZhQ3e`)hnmK0lRnEwxrii+QlF8erG4PjOejhUWlYf@Mf$0&X&e?>V*U~lLGn$pL~!T#Uph5@1r?V;=~ zUtm8AO61AdfVOS4TlZ%9OJ=~v_K%M!ISY_dDT9UX2X?!84vTrj!G?z|T}n8H!>G^q z#gi{D9%zXFsu^XdD-TXbJX%z8J971*NG)5lwzLNTSKJ0UTP+%94hoqkd@7=GBhI7h zut9WiIH>t{~9o!%2KXVFRW;+ySI0lo7Z!q1t zMsXzbpK}aO3hfj*=~Hz8C95uT!vL(zigKg|0Oemy;MJK2iboStw>#UK8sU>VZ6BOp ztW|K0JqsPR)CXlcC^)AZ(og&^v=8{i6GZK4d5$tzKPoWK+hqOHeC-%)Mx&M&_^r`L z@Qw3#rj!okD&&rfliu=wQEI6V&NEPlHKqAyEiBLi>;Qk`zWpIcS`Yg&2Bw-G&* zbkA?T^LYv&Pgt+55uu}?!8cBV84JRsG7KX4;h|!)3#`7rApB=PFaqMPS*OY-Xz277 zo|J@Ua;B^i#Y%TFh=>p=0xFfwbNfemGFt6XoQ;vRkImD5Vm{)%_6)hGiq_|>zGnG$ zcY{l0Gu_e_jH7bTz9Sx?hrTz$Z?F9*{?4EMiw^Q3+5r(m3u)<5tw^3weYud&wOaS< zz|XfyvO zPfD*=9fEkFVbtjNG{zXr`%UkLI4=9>B=8Sk^Z$x%DN+(^1rtg#<6zvT@1%~X6GwuQ zu4EWUu1!YiZZvWgZ#!4z!?;MQ-9`H}1fJI7b3jw*_@m^01Zw^*@UJdgRGV_dSTBd7 zaWan2Dmj<(74(#aCPy5DAG=K!DLLE?j=S=jvY^dAjZfcb@~V>JYCaVIU}0(=nHDF| z`0*FO>!XOB9UOw0nKxQ$fQA0B2CN;vb|1_(Ann7$CxEo8FGxfjf#6`!YVX=W?8WUL zH-!DmmG1PFSK;zbceV3L1AZHJEFU2mz1p2Ko1UC@ zGa0s=IhAW$wen>eIY^X;lE+dTaKspePUK0+8JE-kny3l$5G|IHZgP$^9c8x0!yNuj z!#J5Fc#xd8cE(@k^>@b45Ffv`CzfGUl!9iF$7DC7eMlJDM0~ooWEeCi3o3mo?|_3~ zShxWN!x`(}7xv&5&4(J9lK`WHU4%eZ%>P)P>(;_}&m&^aXA`KwB)rD7?Gx1#V)ii> zX_;WHqlT1}T3kMO32_kApL$4KCr|!^UtBD7JGIQzsz+5U+v01{`}ovklmTMkP-tvi za!K3s(h5CoC#OobT=3h)8_Lk(&$OZX3o8j@xN;PHB2MJ_QSfs{y5{^r3mx^De(UE2 z6JjQB*?%=sMp-ZJDP3+^FAL2LD#4$<-Mn{Ecj8H*C0~p;yxS{l5E{l=5qN@B8*LkH z8{VakVtj@lHf&3E2h^*1X3yVz2FITrYE*qN!5=H;v43sH;9-11va!Ed8G!HXoh+X8|^H2mB%Qx_nEpx^qm5bu}OCn<1(?)lYj@ zT!mi563+Nm`lUk7@LdH@^HBy@!^h~k<24r*WpajIo+&QDbyfss2SaJSfq3h}gJ4V2 z)(t-?e-5xw6_^pj%gZi?_&id`3W(hlCqx2Hkcka_ZzK7{uJ^GuJNr+TMD>5>C4~}; zh0+62Pp+t`W^=pr{!^2~@%*6N6#|n}GX)C?b}yZ{QVa2v71Z(c6jjmvB{wVkIDdsl!Ty zi@N)c8F@xT%4*98K{1jH2Yd>UC`-dEx;$UBiDSYlUeFo!SAbQ-XVl5aYpMO(${E>; z&j=?;T!P6BjLyg(2B@fPdZp>tUPnKnVf_VO{#KS+9)<>xepd1$>7PxQ>+XO`K>g~q z9Ke;>Nk>Gs^-nZs;HDm11I{Te&+`)W8Y!4Ollb*KfY9f^6zTbLoLUbDy|f*VtcObcgE=$HAqH+5=*PNO707jZ)l9?qf|zxhrY!}Wx4GIM97!swt1|+-tF!@}fGRiXqafxm3`8FH zAw$ezTcw`rI%wP5hio2zXFk8&ip@BZv8_N0+O{KR;P}zIoELToSoi3e*l|rLlp5Pd zK;ZRc$Eb+H9We_{iT4uEN-5Sxh(q3DnwtQ9$07;`>W z-^9#+eh@!JNdOLzT&$=Nm7r|DNfeXYk|xp>sRgY1IM7XF%a8HXULEYNlkP-)Qq zQhW;}ffL`flY@hSK8s3PM@B11Q)Tx$I1p)pjPp~uBU_5TetjLzzwrzfM#BAiV`Bq{ zk*Z-Km}v?0YNcp`zRo?+>=E>H9t+31VOPQhw2v%-9;R5A{T0V`*Hc};k_!ifr-`j8 zH*8>2|D|2dFa(uVm^?oIH$}uivWjecPwa>D_>8w($J%+OUGhBqq%){^Da;(UMab8Z z4*T+pZxg6_l8lF&q2h2Vb)!5`NqNng8KWn$ds*`wNmJA05Y^U>C2lsN;Oxy1Nkknet<3nq`zEL#Eg$>JyiuodqA=2Dci@R--^KiI(xM0 zojO0i^u;+lJJCG|+f(Xu41VjI65b_WEHVHq3qvmJLL|Z(J(k%MPbR%=rk|X*)HW!V zKOjqZD4$|42D!Xew1bubpKS&Q$XM&7proVAPmh1RLS`G*(?I$ZP1PuBxpy2ekXM~zU4=1-~?{pqVV}dpW*g& z?TQOHk|?y+%q&FY(R?usJ5X+()mCJI-@4-a)h5=NA8Ob`i;Tk{(u zg`)087;(2c?Krskv~sJG;HGgI$%9JA>f)=p%XukBD#^uJdrE1g`L_&O6Ee)D^NB6k z<-~f;1WTH;8RjPVNq%yw7BRjr(HmyD=G@t*!}-G^IAU*+MLL>J^=fVM$CFOc9*D=< zfs+YyGQ84Q!Gw8~Yg9_xEPdhvu6jTgr#H${#}R6_Yxd*<=a!8EvYnIMqN>6^?YgvI zXN6~b25}Ep0~Q1XWr`h9T%E`0*>&LBuyOizfy~y-$1)BMa$aJHNK7 z>NvSg!1HKaQW|{!15S;py&)|lZta}B(ZtY&F4qZ_w-!~U5Er&@@*{ggkeoac=5Sg0 z;LSZH?2kj`sZ--h4U~nfyA)A+9v-?WQqY2qqnuuN49$Q+TBanX`5Dnebe=nbWZ|X( z41^RT3VUv#2W^S<5F&o&%`10A_uCl{BuJsbS%Hbt8y-< z4qRZYJ0Oj9@lOEDlCUy+Uvn)!hgik01m7#TS|Nqi{%T968tS4?rn38i8YB%}-obwu z=KYOS`7J-^3+Y?NtF%uAu2)qR9@e;}Ha~Lt8-ykLHpv~34-6k5!QuxE$3}h*+uSK%uqL7a4~2ZE;+2O6f~(DUK;~GKx!d& zbn$!oh4`<)?1&>Ul|}j=o!>n0s~=BPB~F8YgBc@`(XQ}da&2O9rk|?HN`}dEWY74i z3PaqPbP~$~o5Xx;vkR2q#%2Yj33VTD$B0(|w?%cBYM@6BI80qHdLIht`@O3zunuqW zrK#6Pufm&m4i-6C&v^7yseA}NT6Ixj>s48QFbqQ-DZHqFv+W1u(tQZ+kaBVsfy;*d z*&C{%jrtNGz$1S{;626|HncUaEN}}nX3u9!Wyn{&()GKjkT^}ti)Xm$U1n@y1GbP$ zuj=p$PhIhJ_23S$gxVnV^@;H;G>Q_5D33AjvfSq;{*H<7fRR+cRH3)ZT8g3o3j)0n zDdkEtj6$ca9^r|%?r0K=VdJK)2LIC>G4JnHIYUMFYhwP}s}U@L7G z&stQ0qd|9p+?^QrCl0}Qe0kSQbM!ym8ldqOwlqwWl0We)cTllFy`j|-^jx*exLcPv zL)dxVWopIgi|B}pjAKiLlbIcXbNzqLYaCw)2-FMA;$WzH@^kVG*_;+YDtCJrtr4Fu zxHRfB>Q6tW4WJ7r}dk3RNm~cl&V{#<5A)VlQ_fBT(fp8)mdI!E~Da~t``3^D=wSIYR z@tH^b&y3a@nO*BcW8N^t!lpNi|OM_Z{&CdPO>E6gE za$2C`x-l_M52mA1V?EHU7p^2)Y>}p)0z?7#Xz-@i;`EDkc%kuw#uWxor;@EusUxqB z^+bN4z{vU5IzUx(4e$GA%)G%q1N?bl-vQXh4GfP+X#I)9opL^BXAk4DoLXV#*4i=G zhFLdq5j;);x9&WrtjVB^;d_I}B{Dpyg3m1X+{fS%`L}`liK63h-}P#nxovLu^p*pR zr|O<{^$nxMw64V}MbQgg-+fD!7RjR*)l*D?5o<@R?ny%0xt!<2#ZwEYbdh|;kz;!C zy-6wJ1$Oy?EG%wE48$WnkYl(N9-VPj4L}95fel!;RVNNuq%uiJNDk-;0BO8uH^C~$ zCrD;=v}{lTpckEH7d3WxX}W!1@m6l!zo)l89f&fflA2dn;0$4> zIH49TIEO7PYnyLfw@!Z(X#Yzr*g_tlxhknS`mQ@|)JiD$in9n?;rtPJRCqDWnPm!p z8@jePBy!NqQb#dhFY8}9b{OKb*2CjWLmGiMd@D;e4`XT%Ebd;$y4#YV8tHOG4v#CF zV1AX9U>6uk(gWn%H90I_sfB7@fM27xq&o1_(sjJF>(mV~Pb zFzLNf4V%v2ExySAGKTA=AvpP6e>myWL_PbErq)*pzEXNITz{Z^+`BgMOUctq25p*;4$80u)9PJ$3ST0M_X-*zrmny&7xbqT^Fj@%NESCDz*C`hZjPaIMQ z8Q{$N@Elmncf~|RzMgK2?Yd2x>P!q7`hZiX_3xB6b7Uu25C%?k{VjX zASI<^fV1!M{k^_l{Bh1&-}=s3>wNx$OJ{~>p69;zz4vwPeO+TC5pwHEhh!-Fr$B--pj z!X-G+S8#wVJm=`TT1=owG;>#OD!q?JT*%!Cjszq!!CtWrcY$`bk&<=c8e9q+N8y63hQ-$2o0@sk$KeTKl1QSW#-1BoKJ+EoTW3kMu2v<5VU483@|DS6q0v&4Q?4K+jqsr_>r$K0g`Q!~_FHVB=>wQ#~-4rNdQSdj3>w zdaPBhC@P_J@rUe_(hjLzkLZ$MEiv}Gz^}gujMdlyh^3RH>lz(BeI&@p5&uDRzWRgO zh9Ym+Q-{f^UsZH}Q*RhCO|R0%pI$$KXRWl&B|F}!askw~wDU(17ZxD5L2+`fT9$>G zgnFwKq&aQ*5Lq05Kqf$h6Kl(N>aM9O^^yFcQnBuZS-fK7SuQaT+d59d$4A3S6Tk3c ze?M?c-z?*5p9xV?Tek0&rq>IH1KF*p{wU(X3XjpPHK=j-vMdSb)vgb7rVT%O-^C}m z%aP9rRV7p*4@@59XIg4D1D-mD%DZFZm8&eGXtqo;l;-9DV%oRfmuiZ})4OD;kSf+o zUi!|oh4rkF4xS1jy2AmM>cHmbo|ckHLu4~#Q>~VXw=`D;>@Hm@hOJ{V|*Sf|>9uZq2+_HIUdxkHS_1-_M{A3tEEo@~Ocy zIf=pP#h!DeQ`HkxQVe_KA?jWXE|hQ zZWcl`_r%!&xRO?u@2~N44rjZf<4$eZ!U@qcWj`^vb(tknlzOgYf~Og#x2x3!FbJ09RIO$HbHk z{L}Xw{>DKzJQBnX?zB)^yY~-P#4&Get8ew<0s+2fiaOsw$P3QVHm<(46df8>F`FY4 z74hhVgg%VIVcDK>oc|k2q1wkVNa($sbu6#$S)MZBD!$hw%J3ZZUD6o>rmFcgqtQ32 zX4+OPVU;c3rnj)2-iS*-95&Ztb6G_n(GxOj%$S>M+n#pI;BT}Do8|Q}1h(v{y7MJA)h`fH5B%rDfxQn&&MxZ zH^>|$WJ7sWSuxWVGjgi-ii$mTAP`6a67?#$#9JS1;j3gWZ1d8;upu%_r*F8}WSYp@ z>2JMVIY_rF*`c_;)N$|SprFiAz^W6LjHFH4aTj2f+>_ewbUd@JtufTTA0(V0u4dq~QYPwD7%gQl?<`0Bo?W|o*;J;1BPp;J22DU&u3FvsZjTF;{5THpQH^w<+>*IY4j&h;xowkR7_CtnlEW%S!WQ@v~bGg^IRfjavFf zpjz_!v#EU)Qe)qBhz4Y9f5`rzE**g{a*`l!mg|kgcc?F+hh9q`7R9lV>+gTy($OFA z?98~UThfk>{G{|307nIfc(qX3rTQqCIk#Spe)H!!jca+8W>?I2@3$+`>pduzsc}cbc@3TjqKc0t*rgzlhfb) zNO~b54WR5!`V$`2tbdlAlodeQvWaC+gWVHvT}>V59V;f2w)*FMA{b3*dG&nezE;%d z?wLZ&<=jCoeSUYnlXHRblbCEWBe3hZz?^Ck_zDe54FJuji81!ZLJ6i{Rm2lHtMPLO;H|Cp+O4XIwDT z_Tm=A4q+b}Hr@|_VmTyzcY#RA+F-xsf}|1u4p34azCX6_2q3v;AM_0OeMmyg8tK&nWyzlNqY zk0E0L&OTg#*q(Q%MdxYgGXu9&@$&bbRUpwARdI)njHr51OBt_k&Pq!s<^@}M_)!IJ zqu%*kd$aQeqMpzsYsq4ayE|E@aWz)=~KznG2@!djLbM_jQjjKg+Pb%!GJ?`NNMsEjCch;sSnU9A7K) zxf2z3Sg*v%ZSxN^*4>+qV=#Ser%zv|O67=|h~eK-!ICKe=hfJO?20IShmcThkN%+P z?DI?SXdzQdRJYbI=)!VtF1TfPiB%@_j%`xh5!uVHRtyPRhTmvdaaM{oH=zQ{;?Ne)ysig*nJn0{?J~9IhmYg-V8RGc(xMrR=orp*2&=RlWcw*;6!hqXBueM(#U4&a zJ$UsoU!tB&?Q-;%fti037?Gp3Pzwoxr`hR*mF+RRL z*!DdH4UU$b`-SU^XQh-M4g$^!k>y-Lz%%NebSN`9HO4J~^b+QMX0HNS;NL8Gp|Y2g z)S-WD$K;cBDnt^AuxepPB%NJ8dW{+CoGnk#qro2QmK!7pQ|okc#NB8CbXhQ%XA_l2 z&HGm&AEpxsG5i{ABFEuYHk6dVvzMk^NBa#Syq0ReqEMl6Y)jQoCvADBE83ODX%y39j`Dy^c&hib@bUA>deFTX=QZ!YC0srGO9&zU$?5m32)Xwo*(4%lF$D z^P_)`AI!Lpm!%0E9QBPy9*;oYV?w9D>6s~`&C?R?=hkKLcHva$ut*q%lXG#+FYgL% z#hsQ(|I)*a6a+w;od3I-dT`93`2^3QD+Q!k$e>B z&qf$Yl`5I}X#ekCFTp%%eAKJfAH7vBwpZ+(2>_UCc;%+zJQhsiGr2=j4se zUuq=-)j1K3k2}_)?q#_xsE89v=|h}-tpGj1ZhU&0QcA-pfmC6&37gsdnV+;nXvyhP z--nU(=pC&>KC4SVLfP5bKQMWdf7J|XR;@%fB#5d>Zjfj9G$Bo<&98@sOvBkpo!XV; z8AVYTnNO{(Gysm1$BY zfP-90-Dd6}iR)ckGMvO^mSE?HI8Dh=JSZm4OqNa6S>;x6z(B^Rw4ornAh)D1Mz10895tmTT7UoDgYD1uq72ho zoaoq+BFk}@NzgP%g)g1Aa_QEAeV_2ys&_tol9H0?iwz%>ucN8tE79J@&)>&Sj3m%h z4HBTujJQ=DSjHpqChwAV7P#V78pbd7XWhzo4Skei^0Zd)V!oNn(cE17Mm5LA>xCVh zlTFT1_(_97AXdZ^q@Om4eb5VYF;hR}lT%jzyPogc5T$q#<(0*$ zGkDL1SR|Jq$^HyUOb0QZ{gibTGy=YH@$<^>^j8)?K_OI$52_i^_9G)w$07v>gfde&yX-crr&=Zcu? zF(Uz=EBWw*m}S*9G@|-zvVS~y@PIjq3j`}*=tg$AR>kX99Er)Hfq!To$^U)`JXDW# zpEp*kHn{BUM6~bk!T2 zh7SpMIXO-RAJ*A#S*;UvAk0B0)JorWnHLMSY{2yihmgAFe~^hc_-(e1(cQ&ZGw##S z(1`QAcI`=jO?Y@BPdL}<@_Nb5CDU(r4f^ht*mnEQN6G#2J$HshhK#3b zUMQkK?)~riKQ0BKF}j*Z=awEwj5ii-y6L>SHsyVWG9m~q0!Y*^&NgM+wr%!J5{of5 z-T5YI%dk*=T9x{bzgvlIG+fTm#&>aKYW=+Gwemr3YNl;HXGYCTCcdLP0GhK{Gk^1O zEr^5&=2Ep5RI%GI4XZv9CV@S7R^=)`w8Zv8kq}(3Fum@+i8az@%LS|V7ePX`zb5lV z!YmGSM8wZWhomjRCbH>Z2F=;A{S%gnCzTHm%*QxkZJ5Kq={-yL?tm8K(_Xq-mLjm^ZN%_D>8}nF^88t4_BvCt zsy%c?IclWjmYwutb%~pv*}6`-SMgFX2u@!u!lOsGdVTH;d<-+q9V3(TLd?v}oLzD> z4O~Brn>EG_?xEu0=jTsLm|LByI=kES9z_(F+>+lsH{d908R5KaVIvbxSEx+@Qgv6r z=`BuJb%QqNG8YUNJKhL% z`uYjkloO|3``L7f93zSPUN+meV#ExBydqU5mM2|ELjvnsHHwNA-bU0g+0E?u>1Hx8 z#nhJP?_K1&ktNVA2NMCh$unwJP&S$Jr$AQpb>b|kWH4c5O{?)PW{hr^tY!U0CvLbK zOgm5)ES&cSp`xtT<=a^U;L%KwGw#NTShkG!g~_|UlJ2;slDcJBTma;B3p$T4tb2ga zj49TVlx|yW4{PKr>>XB#TI;)YDv({tYuLG4;K~LG&jbNzBJQ%Jw9v^m+nC()4x^P9 zJ*%>t$jZL_MLI>hp!m}BJPqTiBf~?Sr*({9pX$d2#N8xWpJ=X6(a{kyv{gZ8!1<-G zzNSj=YmR!4PjauoVNjpzHP0oeqS{HVljOOeU0`7`BC}UwKyn?ZgV=mkp1qzR$Tyha zpwr7y1+sWU{6r8B1~Fc;v|%pMkFWU%tQw!3))}?7HPQ(Mp*|ITNNZyz3BDc$0krB~ zM-=|qYA5{cutMEq;M&FR8I>#i+}E3{HUROLbwpE?`p`aJt(UJGb{10AjD41#*d7-f z%L&7m^KM?hhuvyHf3_mT%B)3^x8%K0L`zT#bjC}#6?o7>G5tDQ@nqBZoOc9Bv&4N6NRB^xpHC-bpYjpt?i^k(VS0uZeOzvR2m*M8mj(SJMhfXm6H z+4PU(7ZdjSG}eak)KC1PW;?Y<;%{sp(9eJq)$Vhe?=5WUIeUkInhdVJGhx*;YK%Xh zE*x)uPqs7egV#HcPR>u_HQs#YE!@MAv+Q*L$cix+ORr@Dg7s4CI%luqi&Rl5{dh`W z97#;A<=`o~>&q6$bjCIR>Wy>lmD78%2y9xD*`hPqOVjhz6A2l&BmYQ8G2+p9+rFuv zUZuH28sV6kHYTjLtZoE=InXHX76f<>qCnc-Bs$DQvJOk|P^OdorwwC4wg8%O@K+AE zHleMUP0O%C6e;1%v7Yc+X-~VA+c~cY>KXwWGK^MO)+co;Kh$LXRGbi9me^>OH4nX* zrN3mtN@qfvGP)Hm(rvx~A9(TNV%vclXq~d8YH@&mXU$~`SDR-ZuO@sb-2qU#O%iH< z(b|uVKXQl)_-X38Cs4@t7x^}Qqm6#}-E!ZBtw=TNRHgCDk5%jW{9;SVrnbMtbSetP5 z&mC75+qz;-F+_%a)^QU%rCn{Bw$KN?K{88C_yFtWR&PF+QLcvLK~iXt4(Wp@-)@;{ zd%M$E68Gn|D4v?0Vj!UQ!?@!)cdSTHnHm=>HT$!h_erAg zxt{eZ%8y4PDWrYr9*9VQ5@|K;QKfAA&dQl=ZqBZ$*{+}jn&lrV1O*6C_c#A@1-}N; zTn1!IpgH97&P7dP?;551LJT0Nh?l5SneQ^i4iYA`6RHd=yLDLQgHt?&p8REm!0{I^49z!=p#XLnUH22o z%djz@oG#yZWlz27=6!@_U@+FCHAk(Div@{aTh``=&*VM^j}oV)l?6G|W9PfgVs^kw zFja-|=6qCXTNlsY-%DBjuZJ9ADe@*TeV*MX`CE87zD?9uOeaO6$0Wi}APh87&~u0t zOqa%E-N<`2mA(<^?wX(80{{A&Cb1J<8#tXkHiCZ0!Gy|u5&H&Wou{lqAyv>`XV(oRo41NQIWFcKqJ7+yS-Q>_5pShC5oNy zBTpa3t@RMC${bnX^;^gnSpFkW~a}JJI!jr3~SmWYBf+73&18 z{DHT-&P0Hz0@8&Vh%pMW!*+cB%ne=<<9So)>0$Qx*$CdBpPv^1`wLDkF2OfFAY)d} zf(7+k0))!(nk`6yrAyYI}l)i(5hX0^ThC6_sdZes}&^q7}}mHKO{= z!KS}bUvg#SgqlH*+M8qWa*X5I-l(7))Zd89#$!9|8uvS0tiMd;zFvQkk&$t5V|{8v z>2)`W#P*QcDF&In2;6w>W4pcwy*Jqkstf2eZ5%Ji&nHXTGN0k*9-r0&w-7;hec$w8 z3rGDF0ti8>p)|VfH3~PFm7Tp*_ah@CP4N*C1B-SOJ6}LYhS+&c3yX~IDyT^~PI=6? zYf=QeQ&L!C1Dh2lK){Tv2iQNDR)LT_uf8C9z2iyvmY{~U?a1NVD0zMd6^3xpTOGwNWU-^kfz();4f9E&~YFr);FBVct2q!_pka40?QyAYsXz*zQhe6E*X8;^H-_VeF4z{J+PPsL zsl>NFiYL6GK`B<;Ij3_rFfdS=>JG^7N)E3y-u60ya=hWT$&@yN%GsvQ*!yD1>#&I; zEZWi@OqZb*?X%D=B9p#<|9+)?&S3oz?|L8Er|j5n2EI}q`-TPvwtD7tb!j1;9OUN_ z1(H2=$TcJ&tMu)S3xGU>u(zW($W0sL z3sxw;_)J0p{SrVpRG!VwJ2Xk0gx>eb8npODVIK}6_cFBl)P}+6DVIESwkiw+S(JIJ z$TPN8wtrpt?(K(oblAY13u)!3vGjDH17QKYSEfj=x1m|DfcMw(Fn+4YigLY4H=t$* z$1_u`>x^+#sBVpBt^xC$DC}oXH77UFa{JhoXH+(N8SSuSGbpP+7um#jn}Icy=V#P- zeVDZT;>C-B(y^RyqzVec*&V@}lxQXK?zl**zAPx#Q^1?>#!85Z>9dp#>Y`VC=jrC@9~>NPT7D6kod7;H7GHUN4iN%UqNZ>X&uolr!no)61`_P1|~Ufv8&+%6P_zTcy*KpKQ(3!+j2 zbHi-w@1JV_^OJHv{>$#eU!+Eo`(zmM`U8>VoA3N;+cgb&U}TDB<)O>h*PC2XUID7e z(Jjy96+vDe3|Z=0Kz?0CVm?AhNN8@vkQH4NQ&4(TR1|$)2GWimeIAbbR|OnLR8cZ# z0;x^D$Fe=LJ*;uCw--C#r0?9vjvTNq%F5P)60pU+df1}KG=$XNUJI&@ClLk>O35%R z1m0Jw1%|M(qCcTian9tgrSUs$MDzyZS=$K6WtF3NbUCUv)~1xD2(fQ(u$??v4`ynX z_i7`#H0!YIzxFPJ%@9T2DeQ!N9jt$wFBI>~mHn{qLH)=CY>%#KXqetBz7)>kD&Ylt z@FUEun0yF0C;(0kzFv6r;S>ovx!@!0x<%Hbt-`bMpkjvU+62{<5yXcm2TQ(l5dH8s zRP_N(H^q9dlX)vbsiG`FPE22nl2=3SNOeC`BU@kNOTbPnjU)?kaEZ<%!$g zy`yoXMPMoP&nV~KgQS_y_Bn<#$nrZ+>IwFvvIs-D6JWR5P+3~qGxY;R`%H7U42fGc z#tElgye=Lq2~>@MRY%s93dw($1XJLwtu(# ztmC_OO6Xby7Q#H(x0&HSK%#pgSxIgxabL7W>f8UaGQzd}d8x~IUJV4ZI13VTCRjbc z4sFIUYrxttl9q)|xKuNk#mwsC+SO;?A5d{z6-G-$${E;&!-o!?{NIjr2E(nmN6>O! z1ZUk|dpKt64A*B4wJH71y#;zjBCjG~lVMk$%dcAuXKfP@wPiZ_6^>RmLBTdh>iO$n z%;@Usn#M+IOLYFisTjo_1`dmM=a^;+@W9otHpZXLm9ILA?(zr?aAgn`^Y47S;0iU- z0BpEO7+BQ(w@BYwWZ(->r*ue?`kk81v0vqZKNX&|+e3t%Sev!bS$Awds>F-*WsrX+ z#tFo&(N7WC|M~e}avw}qeO`hA6&R1Q)HXIof_5TmnbAc*=q7BLG+roHs>(jyE5o7{{>(d*<*z) zp3u?JK_-vp07Pu!&chb_e&^i4y1L2<;|4+ar%1-lAzQmZ4#C3?le)Ggsq$5a(DjXE z{SMntS618@gv=jDL`K#^+Mz7h+(s+UbR59tDA33L2&qAjL??jb?BF6}O!dm9m&2EO zuM<{7Q`0OzB<}cUqE)nOlP~UH75?58CirkEL&_+ih)gjEvLB!cVGyi7dHDJvLyx@f zCQ4oH37l&yRPiXA(Bw;Z7988GN`{^5+S5TkGO@A5=p#lv+Dl)5V&B{Z#9 zQd5&4lVcsEG4SzBAbu7MBm zQFsjQ5|i#Nvyi9I$b*4##mbxJy=f?)ePmtX*-uz3*SNM#qP~dXZA1iJ0Z8>Nth#{s zdiNOj8`Y%DGtRWBy$9fPB<}Q^9sN&AU4Yt>pXTH zf;@}+c;1t!C{xR4RU7N>_?mtw`U^T4?lFtbHV7gqdE^z<{pvQp(?~4Fz>J~#{riug zl;0lQk8T0RG1z9yTTsG$H%P0Z{H< z6zfFRUg$)JXHGEz%gbw7>w=^5G!lCMa8UCj5a<7)w9SXgSNnHydj%mtf?RiibA0lj z5GbCX=An4016M^Pc`qdWKa)YtQm*CpseeM9$ zVcKVS<;s=jVPq@_^V@o8(S~z+fWSXu^U*l5!+9{Ee49vB>`B~m8g4@A-bK#^T4Zb8 z+Ixs{TeeHULSR? z)@9}9=qJoDaL|vTDATgEv^1U>s6~cu-BsRIXmveFNZ zxOMTxfw6!=jRWA<;TRd zFgm=I`Ii3W|FQTBO=2TojCG?WnD~mJxuv2Hr@hqkv5D16NIfZS1DlIbg}pvUz?OJ_ z+W`N%kH|NI#jwJS2*Sf#al0XG3%^OGDvDD=u8N}TL-Ducq<-~pto19W@pZkwH&J*j z3%XSbWH)+>th-xnhLNSE^`~XfHzhj0g5o#c0oY|~k1MjW4_vQ+*0LfnCPfnX}SP5MKLD@Tv#*@C- zEL271v!Wx>1PIlaoBQSg0Eq9jD3LNUdPau3jz<>7+zstGk7#|TSenCpQf^PEa#jRe ztX#p7%Hy&e-hEQ^fDn416D?zK%_Dn0FK$cQvH#%6dTXh(O&Kr$zA;y~{uhgZHWr)Z zEOwkGgPu|ta^9{ziRXs)2#zi3$d9?>{TlKxyNj1J`$@`}lrje#Wd;;@>%hcRi7NL* z+(g?~K=@R^sDy=tLk583^Jj%hHEu&4V-VW!I-H1{d5gVu+tk)!{4g#}05Y~R^3=w9 z?y_n$$fAFB0ymi%SSFWjZEZsh(8_fFT6ua;}~|&x#)s%381`Ha1fmD zn(d}#fA(}mT3){X==wCZGhh1p5A6E8!lm{rS5SElUUfZgnulJW-W_l+RayJqZYuSE z;k~9|c~r^JV+DS&AiB^1l;`IX2g2NQgoL2V#w+ldg*Okr{aObk9|wY3=^&H6ziV=J zbK48Pd5Frz2M*BN@GXHmV4H{j)vL6mrqcZU*75KsPXLhabEkHf6o-iyTK)b`k$0&Z zdCf)T8V}Qova-HH4&ZAb?*bW-)6ddEz3Ubw=}xYtsQWm7 z?qYLA5sj^)qR#x;b7Bim3Fh?I`gMJ!69bLbxC@!{qv|cCUW{?h#~lR|OO`S~;(z~c z)NyoR$>LzbLf6ZY3j9KNGe^*yg_kcUO@zz3zQoB&oTaR&5U=_c=BjN_BTtK_z4;2v z`#4Ui;E9HmxydPcm}eFUveA}NU7YAWDIwcQZK;~RAw9i#RCPDK@Ud~FQEpfbx4%{9 zdL9|K5R_KlI%43xjD<3Bv0Uolxc%{phw6WgLw_zEesE^<+wFv4E5}_I89QBa*sT?} z2oL7++;Ps6Oa~y^>*%Wx>QXt_3ioR~@v;YK#b&Z5x&#|pPBVAY)9Bkj@5s_NdePY9 zbOcP+QoF4dJ(uL|avDdAci2pof#^w_LK+W%;wyUEDfe?Oitp~i6LQtUWTItnLsa<%Vuuwybi6)J>XiG z6T~d80S-rG+mZ!^i?yc)&Q>i4bL$m1lOIZz1zy2R>IVb{HY#0c?2>?n6akwap((+G;IQX}EXf--> zyJ9{{+?-_95o8AD=7^9He#1xpadL~ARrb*oFrj@*^PqFtJMIM@?D;-JkB&VU7CX8r zqq4F*q`kA#o!M$t_bHU3(WZyjz?j5j-FFTSj2KseBZpB)6t2n$@b@2Wv4V?xWD_>?^y{fJ-W!PHt4H9p2J`yxBf&yanAu>M2G zl?12#?J1&0@KG3_iI;v9K)@OdJkUS~s1T`2bBsIy!Ev zfGBO(Y;SL;blEB@hC`R@!onb+BAi?QLIM%@yb=V!PTaf;a2}4YhtEU0JS6(+vwh&I z7CKzM?e%`lAZV%p_F4#L4*{cfO0sx(PJN2Ctp`L5mdXU0aLHz!qx<+Xk|gheOo5(hxH2;GE-IG0C|xz%1t2+(y>q zo-ANPUEpdBNynrSx^7XRIirb8=kC1rEQddXkaY-zuEBGd7E^I@DiW2v^Yt|{C0#0S z0`K)3EZ$)F>A|84whyAOOuoH+FjN8^d#RnXP!aJvkRk80L3U}YOF8;wI@O^^Z?m{V z3@JAd1g_5EJSS&{38b@=2&CevVR8s^9Y<`#;xIKv%Iq;*>l`Pl#cdZTZq4J#^9i1- z3$+Nkzu4}_0O-w6>sn@*q^ys`VdsI2y$-gV z@jj`EcR|Lx4=8qJQ7hfy1c#8hss8?mCzIU;HN$q^xqwFqyYoEQhDk0%ofRugTwe<| zOA&$PE|6381*zOf5yPu->?Bj}^&+BGXWS5f>3VK9AfGFq8ym~`4gO$LN1mr5cNw6{ z+QDMz@@-p2cJ{>dit|K|$wJTL>Z29BV|j_<&MW7WkgIw_-Q|w5tbd?F$p zTLWzbEs(Dmlz&+G~WeosAcou?Knc? zwQUDxWVX>nXnPyc=?I&f=@9B=@b~xUzxynQef*Nn_Y7ro5_lx^c;-Z<{7h@K0F+Y= z>Tvfd2~HlK$ULK(I9v$e&h(T=`dpCg*!LM39izTM&O^j}t2kmC@xEBG=hT-9$>El2 z9#E@x`R;#`EaHx+**^AE=8|uIj12~5zB>Afkx7f_m|9)|)aWM(w+WD5)KfBdsYlom zPVSj1XmU=|yY4Hqdw*|h%kCrlESnc0b&i{dIowPr37|5K^-(n>Z29Sn1G~6d zpM$Zqq_55W<~tHOk`^>&o_UbWU+g$hT}S5$GO zX{rUDsPS-c}r#EXjIUT6H=}d6lCI(?3If-7jE49Uz!1m=>Px# literal 0 HcmV?d00001 diff --git a/docs/src/perf/timings-2026-06-20-verbs.png b/docs/src/perf/timings-2026-06-20-verbs.png new file mode 100644 index 0000000000000000000000000000000000000000..32a0c901063fb2acc2c5aec6066fb4a76f70f408 GIT binary patch literal 40555 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 literal 0 HcmV?d00001 diff --git a/docs/src/performance.md b/docs/src/performance.md index f8d8fc53c..2240afc10 100644 --- a/docs/src/performance.md +++ b/docs/src/performance.md @@ -83,6 +83,10 @@ The table below compares wall-clock time before and after these changes, using t | `put` UDF-heavy | 2.81s | 1.71s | -39% | | `put` map-returning UDF | 2.72s | 1.92s | -29% | +![perf/2026-06-20-verbs.png](perf/2026-02-22-verbs.png) +![perf/2026-06-20-cats.png](perf/2026-06-20-cats.png) +![perf/2026-06-20-chains.png](perf/2026-06-20-chains.png) + Peak resident set size (RSS) for representative workloads: | Workload | Before | After | Change | diff --git a/docs/src/performance.md.in b/docs/src/performance.md.in index a414dd7fc..349618072 100644 --- a/docs/src/performance.md.in +++ b/docs/src/performance.md.in @@ -67,6 +67,10 @@ The table below compares wall-clock time before and after these changes, using t | `put` UDF-heavy | 2.81s | 1.71s | -39% | | `put` map-returning UDF | 2.72s | 1.92s | -29% | +![perf/2026-06-20-verbs.png](perf/2026-02-22-verbs.png) +![perf/2026-06-20-cats.png](perf/2026-06-20-cats.png) +![perf/2026-06-20-chains.png](perf/2026-06-20-chains.png) + Peak resident set size (RSS) for representative workloads: | Workload | Before | After | Change | diff --git a/scripts/perf/README.md b/scripts/perf/README.md new file mode 100644 index 000000000..6288211ad --- /dev/null +++ b/scripts/perf/README.md @@ -0,0 +1,78 @@ +# Miller Performance Benchmarks + +Scripts for reproducing the performance graphs at +https://miller.readthedocs.io/en/latest/performance/ + +## Quick start + +``` +# Once — if ~/data/big.csv doesn't already exist (run from repo root): +bash scripts/perf/prep-perf-data.sh + +# Collect timings and render graphs (run from scripts/perf/): +cd scripts/perf +bash run-perf.sh ~/bin/mlr-6.18.1 ~/bin/mlr-6.19.0 +``` + +That runs `time-verbs.py` with both executables (5 reps each, ~18 cases), +saves `timings-YYYY-MM-DD.dat`, then calls `plot-timings.sh` to produce three +PNGs: `-verbs.png`, `-chains.png`, `-cats.png`. + +## Prerequisites + +- Python 3 +- [`pgr`](https://github.com/johnkerl/pgr) (used by `plot-timings.sh` to render PNG graphs) +- One or more Miller executables to compare + +## Step-by-step + +### Step 1 — Generate test data (one-time) + +Run from the Miller repo root: + +``` +bash scripts/perf/prep-perf-data.sh +``` + +This creates `~/data/big.csv` (~1 million rows) and derived files in DKVP, +NIDX, XTAB, and JSON formats, plus `small.csv` and `medium.csv` subsets. + +### Step 2 — Collect timings + +Run from `scripts/perf/`, passing one or more executables to compare: + +``` +python time-verbs.py ~/bin/mlr-6.18.1 ~/bin/mlr-6.19.0 \ + > timings-$(date +%Y-%m-%d).dat +``` + +Output is DKVP, one record per (case, executable): `desc=...,version=...,seconds=...` + +Five reps are averaged per case. Cases cover: + +- **Verbs**: `check`, `cat`, `tail`, `tac`, `sort -f`, `sort -n`, `stats1` +- **Then-chains**: one to four chained `put -f chain-1.mlr` steps +- **Formats**: `cat` across CSV, CSVLITE, DKVP, NIDX, XTAB, JSON + +### Step 3 — Plot + +``` +bash plot-timings.sh timings-YYYY-MM-DD.dat +``` + +Produces three PNGs alongside the dat file: +- `*-verbs.png` — verb timings +- `*-chains.png` — then-chain depth +- `*-cats.png` — format comparison + +## Files + +| File | Purpose | +|------|---------| +| `prep-perf-data.sh` | Generate `~/data/big.csv` and format variants (one-time) | +| `time-verbs.py` | Time each verb/format/chain case; outputs DKVP | +| `chain-1.mlr` | DSL script used for then-chain benchmarks | +| `run-perf.sh` | Wrapper: collect timings + plot | +| `plot-timings.sh` | Read a `.dat` file and render PNGs via `pgr` | +| `timings-2026-02-22.sh` | Original one-off plot script (hardcoded filename) | +| `timings-2026-02-22.dat` | Timing data from the February 2026 run | diff --git a/scripts/perf/plot-timings.sh b/scripts/perf/plot-timings.sh new file mode 100755 index 000000000..3f7f5aeaa --- /dev/null +++ b/scripts/perf/plot-timings.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# Usage: plot-timings.sh timings.dat +# Requires: mlr, pgr +# Run from the Miller repo root. + +set -e + +datafile="${1:?Usage: $0 timings.dat}" +stem="${datafile%.dat}" + +mlr --d2p --from "$datafile" \ + grep cat then reshape -s desc,seconds \ + | sed '1s/^/#/' \ + | pgr -cat -ymin 0 -flabels -lur -lp -ms 5 -o "${stem}-cats.png" & + +mlr --d2p --from "$datafile" \ + grep chain then reshape -s desc,seconds \ + | sed '1s/^/#/' \ + | pgr -cat -ymin 0 -flabels -lur -lp -ms 5 -o "${stem}-chains.png" & + +mlr --d2p --from "$datafile" \ + grep -v cat then grep -v chain then reshape -s desc,seconds \ + | sed '1s/^/#/' \ + | pgr -cat -ymin 0 -flabels -lur -lp -ms 5 -o "${stem}-verbs.png" & + +wait +echo "Plots written:" +echo " ${stem}-cats.png" +echo " ${stem}-chains.png" +echo " ${stem}-verbs.png" diff --git a/scripts/perf/run-perf.sh b/scripts/perf/run-perf.sh new file mode 100755 index 000000000..bf25912d4 --- /dev/null +++ b/scripts/perf/run-perf.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# Usage: run-perf.sh mlr-executable [mlr-executable ...] +# Run from scripts/perf/. + +set -e + +dir="$(cd "$(dirname "$0")" && pwd)" + +if [ $# -eq 0 ]; then + echo "Usage: $0 mlr-executable [mlr-executable ...]" >&2 + echo "Example: $0 ~/bin/mlr-6.18.1 ~/bin/mlr-6.19.0" >&2 + exit 1 +fi + +datfile="timings-$(date +%Y-%m-%d).dat" + +echo "Collecting timings into $datfile ..." +python "$dir/time-verbs.py" "$@" | tee "$datfile" + +echo "" +echo "Generating plots ..." +bash "$dir/plot-timings.sh" "$datfile" diff --git a/scripts/perf/time-verbs.py b/scripts/perf/time-verbs.py index 0dc31e6f4..5e4921c03 100755 --- a/scripts/perf/time-verbs.py +++ b/scripts/perf/time-verbs.py @@ -5,6 +5,9 @@ import sys import time import subprocess +script_dir = os.path.dirname(os.path.abspath(__file__)) +chain_mlr = os.path.join(script_dir, "chain-1.mlr") + # ================================================================ def main(): mlrs = [ "mlr" ] @@ -28,10 +31,10 @@ def main(): ["sort-n", f"--csv --from {in_csv} sort -n quantity"], ["stats1", f"--csv --from {in_csv} stats1 -a min,mean,max -f quantity,rate -g shape"], None, - ["chain-1", f"--csv --from {in_csv} put -f scripts/perf/chain-1.mlr"], - ["chain-2", f"--csv --from {in_csv} put -f scripts/perf/chain-1.mlr then put -f scripts/perf/chain-1.mlr"], - ["chain-3", f"--csv --from {in_csv} put -f scripts/perf/chain-1.mlr then put -f scripts/perf/chain-1.mlr then put -f scripts/perf/chain-1.mlr"], - ["chain-4", f"--csv --from {in_csv} put -f scripts/perf/chain-1.mlr then put -f scripts/perf/chain-1.mlr then put -f scripts/perf/chain-1.mlr then put -f scripts/perf/chain-1.mlr"], + ["chain-1", f"--csv --from {in_csv} put -f {chain_mlr}"], + ["chain-2", f"--csv --from {in_csv} put -f {chain_mlr} then put -f {chain_mlr}"], + ["chain-3", f"--csv --from {in_csv} put -f {chain_mlr} then put -f {chain_mlr} then put -f {chain_mlr}"], + ["chain-4", f"--csv --from {in_csv} put -f {chain_mlr} then put -f {chain_mlr} then put -f {chain_mlr} then put -f {chain_mlr}"], None, ["cat-csv", f"--csv --from {in_csv} cat"], ["cat-csvlite", f"--csvlite --from {in_csvlite} cat"], diff --git a/scripts/perf/timings-2026-06-20.dat b/scripts/perf/timings-2026-06-20.dat new file mode 100644 index 000000000..0d9b8ffef --- /dev/null +++ b/scripts/perf/timings-2026-06-20.dat @@ -0,0 +1,36 @@ +desc=check,version=mlr-6.18.1,seconds=0.614 +desc=check,version=mlr-6.19.0,seconds=0.217 +desc=cat,version=mlr-6.18.1,seconds=0.620 +desc=cat,version=mlr-6.19.0,seconds=0.223 +desc=tail,version=mlr-6.18.1,seconds=0.606 +desc=tail,version=mlr-6.19.0,seconds=0.210 +desc=tac,version=mlr-6.18.1,seconds=1.066 +desc=tac,version=mlr-6.19.0,seconds=0.463 +desc=sort-f,version=mlr-6.18.1,seconds=1.120 +desc=sort-f,version=mlr-6.19.0,seconds=0.521 +desc=sort-n,version=mlr-6.18.1,seconds=2.696 +desc=sort-n,version=mlr-6.19.0,seconds=2.008 +desc=stats1,version=mlr-6.18.1,seconds=0.678 +desc=stats1,version=mlr-6.19.0,seconds=0.549 + +desc=chain-1,version=mlr-6.18.1,seconds=1.052 +desc=chain-1,version=mlr-6.19.0,seconds=0.719 +desc=chain-2,version=mlr-6.18.1,seconds=1.096 +desc=chain-2,version=mlr-6.19.0,seconds=0.759 +desc=chain-3,version=mlr-6.18.1,seconds=1.188 +desc=chain-3,version=mlr-6.19.0,seconds=0.881 +desc=chain-4,version=mlr-6.18.1,seconds=1.357 +desc=chain-4,version=mlr-6.19.0,seconds=0.959 + +desc=cat-csv,version=mlr-6.18.1,seconds=0.638 +desc=cat-csv,version=mlr-6.19.0,seconds=0.233 +desc=cat-csvlite,version=mlr-6.18.1,seconds=0.703 +desc=cat-csvlite,version=mlr-6.19.0,seconds=0.289 +desc=cat-dkvp,version=mlr-6.18.1,seconds=0.949 +desc=cat-dkvp,version=mlr-6.19.0,seconds=0.462 +desc=cat-nidx,version=mlr-6.18.1,seconds=2.058 +desc=cat-nidx,version=mlr-6.19.0,seconds=1.559 +desc=cat-xtab,version=mlr-6.18.1,seconds=0.767 +desc=cat-xtab,version=mlr-6.19.0,seconds=1.305 +desc=cat-json,version=mlr-6.18.1,seconds=7.890 +desc=cat-json,version=mlr-6.19.0,seconds=7.512