Komentáře k článku
Zvyšte rychlost vašeho JS kódu

Pokud je pro vás rychlost kódu důležitá, neměl by vás tento článek minout. Je možné, že objevíte něco, co můžete ještě zlepšit.
Pokud je pro vás rychlost kódu důležitá, neměl by vás tento článek minout. Je možné, že objevíte něco, co můžete ještě zlepšit.
Jaký je smysl první rady?
Pokud potřebuji vyhodnotit „2“ porovnáno s 2 jako false, tak automaticky použiji ===. Pokud chci aby byl v tomto případe výsledek true, tak použiji ==. Navíc píšete, že pokud bude porovnání 2 == 2 bez rychlostního postihu, tak je to jedno.
Re: Jaký je smysl první rady?
Když pochází jeden operand zvenku (třeba jako vstupní parametr funkce), tudíž nemáte kontrolu nad datovým typem, a potřebujete, aby se striktně rovnal nějaké hodnotě, je škoda ztrácet čas typovými konverzemi.
mikrooptimalizace
No jo, ale pokud použiju nějaký framework jako Angular nebo Knockout a jiné, tak ty bottlenecky jsou někde úplně jinde a tyhle drobnosti už mě nevytrhnou.
Pak mám pocit, že spousta tipů může přestat platit, když vyjde nová verze prohlížeče. Takže mi vůbec nedává smysl nadřazovat v těchto případech výkon nad čitelnost.
Re: mikrooptimalizace
Máte pravdu s těmi frameworky a v takovýchto aplikacích by se člověk měl zaměřit spíše na čitelnost a přehlednost, než aby aplikoval zmíněné techniky. Podle mě je jejich využití v nějakých menších javascriptových knihovnách, které pak budu třeba ve své aplikaci využívat. Dobrý příklad může být knihovny pro buildovací nástroje, které můžou pracovat nad velkým množstvím souborů a pro vývojáře je pak každá ušetřená milisekunda při buildu určitě potěšením.
A co se týče nových verzí prohlížečů, máte pravdu, ale v mnohých testech na jsPerf, kde bylo otestováno více verzí prohlížečů, zůstává většinou vítěz stejný (ale objevují se i výjimky).
Re: mikrooptimalizace
Dobrý článek, škoda jen, že jsou ty techniky uvedné v pořadí od prakticky nejméně důležitých (dělení mocninami dvou se uplatní opravdu jen v extrémních případech) po velmi důležité (práce s poli).
K těm polím bych dodal, že všechny funkcionální metody (map, reduce, atd.) lze napsat mnohem rychleji prostým cyklem, a to nejen proto, že se ušetří volání funkce, ale taky proto, že ne vždy potřebujeme robustní implementaci dle ECMA normy, která zahrnuje různé type checkingy a hlavně ošetření sparse arrays. Další pomalou metodou je Array.prototype.indexOf – pokud pracujeme s dense poli, pak je mnohonásobně rychlejší ruční for cyklus. To se v nových verzích prohlížečů asi jen tak nezmění.
Podobné techniky jsem použil v jednom svém frameworku a opravdu to udělá dohromady klidně stovky procent výkonu. Jde o situace jako tisíce data-bindingů na stránce, kdy jsou podobné mikrooptimalizace znát. Takže pro knihovny a kritické části kódu rozhodně ano. Nevím, jak je na tom s optimalizacemi třeba právě Angular, pomalý je celkem dost. Knockout je naopak překvapivě docela svižný (aspoň co jsem testoval).
Re: mikrooptimalizace
Ostatne to s temi prohlizeci plati vsude. Kdyz clovek pise v asm, tak to jiny procesor muze resit jinak, v C++ jiny kompiler atd. Takze vzdy pouzivat profiler a menit jen veci ktere jsou nezbytne nutne.
Uz jsem zazil pripady, kdy se jednou mikroopt. zkratil beh na 30%, u jineho programu na 18% casu, ale bez profileru bych na to neprisel. Take pak uz nebylo zrejme jak pokracovat, casy ve zbytku kodu byly ocekavatelne a nic nevycnivalo.
Předčasná optimalizace
V článku chybí asi nejdůležitější informace — při jakékoliv optimalizaci je nejprve potřeba najít úzké hrdlo aplikace, kde dochází k největšímu zdržení — zrychlovat jiné místo nepřinese požadovaný efekt.
Nejprve je potřeba měřit pomocí profileru a pak teprve konat. Navíc v případě JS je potřeba měřit ve všech prohlížečích, protože různé JS enginy mají různé optimalizace.
Re: Předčasná optimalizace
Tento článek neměl být úplně o optimalizaci aplikace. Spíše jsem chtěl ukázat rychlejší varianty základních operací. Ale máte samozřejmě pravdu.
V 99.999 % zcela zbytečná optimalizace. Jak píše Kosek, nejdřív měř.
Re:
Samozřejmě správný postup je měření -> hypotéza -> kód -> goto 1. Tenhle článek nedává žádné informace o prvním kroku, ale může se hodit u toho druhého a třetího.
K procházení polí
Za zmínku myslím stojí připomenout, že v případech, kdy se iteruje přes pole, které je ‚dense‘ (bez děr) a bez hodnot konvertcích na
false
, nabízí se pár postupů, které ani nejsou tolik znečitelňující, například:var i=arr.length; while(i--){arr[i]}
, což se vyplatí zejména v IE.var el, i=-1; while(el=els[++i]){el}
což je výkonově srovnatelné s ostatními navrhovanými obšírnostmi a pořád celkem neukecané.Podobná hustá pole bez nepravdivých hodnot jsou v běžné praxi myslím dost častá: všechna pole objektů což je mimo jiné i každý obyčejný
NodeList
vzniklý nějakýmquerySelectorem
nebodocument.getElementsByXY
je přesně tenhle případ (jsPerf s iterací přes pole HTML prvků).Mimochodem, do jsPerfu aktuálně odkazovaném v článku se vloudila drobná chybka do čtvrtého testu:
while (i++ < len) { arr[i]; }
‚přeskočí‘ první prvek a na konci ‚vrátí‘undefined
. (Mně se tohle taky stává každou chvíli :])Bitové operácie sú však len na 32 bitové čísla, teda sa môže stať, že to v dôsledku tej optimalizácie „pretečie“.
Overenie vlastnosti v objekte spôsobom obj[‚prop‘] !== undefined nerobí to isté ako ‚prop‘ in obj, lebo zahrňuje aj možnosť, že vlastnosť prop v obj existuje, no má hodnotu undefined.
Pokud pracuji s nějakým jazykem, měl bych se přeci naučit jeho syntaxi a vědět, jak funguje a jak se liší od ostatních. Nemůžu čekat, že jazyk pochopím na první pohled jen proto, že je C-like. A použití !! je prostě běžná praxe.
Tohle ale nebude fungovat u čísel přesahujících 32 bitů, neboť tento operátor pracuje s běžnými integery. Tím pádem ani nepočítá s desetinnou čárkou. Bylo by vhodné to zmínit.
Tam žádné záludnosti nejsou. Človek holt jen musí vědět, že když vynechá druhý parametr, bude ho funkce odvozovat podle vstupu.
Která však při vstupu „-25.5“ nesprávně vrátí -26. Co se týče ostatních metod, tak společný problém je, že číslo neparsují, ale pouze string přetypovávají. (Tedy např. ze stringu „25 Kč“ nic nedostanu.) U
str | 0
je stejný problém jako u bitového posunu, pracuje pouze s 32bitovým číslem. U stringu, kde vím, že je to prostě číslo, mohu jednoduše (a přehledně) použítstr * 1
.Mě by spíše fascinovala ta možnost, že by se to chovalo jinak. Při prvním přečtení mě to úplně zmátlo, osobně bych tohle z článku klidně odstranil nebo to napsal maličko jinak.
Ale s tímhle zase pomalu. Funkcionální způsob bych rozhodně neodsuzoval, neboť může v mnoha případech velice zkrátit a zpřehlednit kód. Na místech, kde se neprovádí složité výpočty, to uvítám spíše než for konstrukci.
Co je, prosím pěkně, toto za blábol? Cyklus for-in nikdy nebyl určen k procházení indexovaných kolekcí.
Vřele doporučuji vyhledat si rozdíl mezi použitím in operátoru a porovnáním s hodnotou undefined.
Opět bláboly. Metoda concat opravdu, podobně jako String.concat u stringů, slouží ke spojování polí. A je to jediná metoda spojování dvou polí do jednoho nového. Jedná se tedy o něco absolutně jiného než použití metody push, která pouze rozšíří první pole. Je to zvláštní, že vytváření nového objektu zabere více času, že? :-)
Re:
Re:
Ano, to jsem přesně říkal. Pokud jde o parsování, je toto jediná možnost.
Asi se jednalo o nějaký univerzálnější test, to bych neřešil.
Jak jsem psal výše, to člověk musí znát, pokud chce používat JS. Stačí se podívat do dokumentace. :-) Druhý parametr určuje číselnou soustavu. Např. výraz
parseInt("f", 16)
tedy vrátí číslo 15.Re:
Myslel som druhý argument funkcie parseFloat – ten je tam na čo?
Re:
Aha. Tak ta nemá žádný druhý argument. Takže to na funkci nemá vliv. ;-)