Emulujeme a optimalizujeme…

Takový podotek k předchozím článkům. Jako po hodech následují vrhy, tak po vývoji následuje ladění.

Emulátor PMD jsem psal a ladil v Chrome. Webkit is the new IE, takže je to logické. Navíc je i dostatečně rychlý a podpora nových technologií je výborná. Ale pak následuje ta otravnější fáze…

Pamatujete, jak jste odladili web ve Firefoxu, pak zapnuli IE, vzdychli a začali upravovat? Tak dneska je FF v roli toho IE. Mně emulátor fungoval v IE, Opeře (která je vlastně Webkit taky) i Chromu. Pak jsem ho zapnul ve FF a nestačil se divit: Pomalé to bylo, vleklo se to, dropouty neskutečné, co mělo proběhnout za sekundu běželo pět sekund… Bylo jasné, že tam je něco hrozně pomalého. Ale co?!

Chvilku jsem laboroval s tím, co by tak mohlo pomoci, zkoušel jsem zmenšit displej, zkoušel jsem zmenšit počet instrukcí, a nakonec jsem použil profiler. Bylo vidět vždy krátké vzepjetí, pak dlouhá čára střední zátěže, a pak pauza. Šel jsem bod po bodu, a zjistil jsem, že:

1. jsem naprosto nepochopitelně strčil tabulku příznaků nikoli do objektu, ale do funkce „step“, takže se při každém kroku procesoru vytvářela znovu! Přehlédnutí o tři řádky, ale krvavě zaplacené taktem procesoru.

2. jsem zapomněl v kódu obsluhu přerušení. Pryč s ní, není potřeba!

3. nic z toho nepomohlo nijak výrazně.

Zkusil jsem nahradit pole konstrukcí

Pomohlo to znatelně, emulace jádra procesoru se rapidně zrychlila, ale stále tam byla ta dlouhá pasáž, co každých 20 milisekund zabrala asi tak 80ms. A jasně, bylo to vykreslování displeje canvasem.

Pro každý bod se použijí čtyři přiřazení (RGBA). Bez toho to nejde. A protože mi každý pixel z PMD zabere čtyři pixely canvasu, je to 16 přiřazení. Samozřejmě si data z getImageData uložím do jiného pole, ale i tak to je pomalé. A Google mi dal zapravdu – „canvas drawing slow in Firefox“, „Horrible putImageData performance“ a tak dál.

Ušetřím něco, když data nebudu číst (nepotřebuju je) a jen je zapíšu? No, nic moc, žádná sláva. Nejpomalejší bylo opravdu to přiřazování do pole. Takže zase TypedArray. Tentokrát Uint32Array. Tím můžu pořešit jeden pixel jedním přiřazením. Zápis do image data pak řeším druhým pohledem na tentýž buffer, konkrétně typu Uint8ClampedArray.

Vyzkoušel jsem, a výsledek byl ohromující! Zrychlení ve Firefoxu dobře o jeden řád! Dokonce stíhal i hrát zvuk!

Takže rada: Kde chcete ukládat malá celá čísla do pole, použijte typové pole. Při kreslení po bitech do canvasu je to pak naprostá nezbytnost. Ukázkový kód najdete na jsFiddle.

Optimalizace samozřejmě ještě nekončí, ještě tam jsou místa, která můžu zrychlit, ale to jsou spíš už jen drobnosti. Největší výkonnostní díra bylo právě to vykreslování do canvasu přes obyčejné pole.

Líbil se vám článek? Podpořte autora na Patreonu

Got Something To Say:

Vaše emailová adresa nebude zveřejněna.

banner

Copyright © 2017. Powered by WordPress & Romangie Theme.

banner