Rychlý Javascript

od aichi E-mail

Každý by rád rychlé JS aplikace, ale jen někteří se optimalizací zabývají a jen pár je opravdu posedlých optimalizací na každém řádku kódu. S pár takovými programátory jsem se nyní potkal.

...

Setkání to bylo věru tvrdé a proto napíši jen pár postřehů. Varovat proměnné je nutné pouze jednou a to vždy na začátku funkce pouze jedním příkazem var.

Dalším hezkým případem velkého urychlení je získání délky pole. Normální programátor přistupuje k atributu length při iterování přímo v řídící části for, ale to je chyba. Správné si je tuto hodnotu uložit do lokální proměnné a tu použít.

Když jsme u těch cyklů, každý ví, že pokud nezáleží na pořadí procházení položek pole, je výrazně rychlejší je procházet odzadu. Člověk by se spoléhal na chytrý JS engine, ale chyba lávky.

Dalším velkým zpomalením je volání metod, nebo získávání hodnot ze vzáleného prototypového řetězce. Je vždy nutné si udělat alias (referenci) a ten důkladně používat. Už nebudu zdržovat a nabídnu ukázku:

function makej(pole) {
  var i,
      res = 0,
      sqrt = Math.sqrt,
      len = pole.length;
      
  for (i = 0; i < len; i = i+2) res += sqrt(pole[i]); 
  return res;
}

Srovnejme ji s klasickou funkcí, kterou by napsala většina z vás takto:

function makej2(pole) {
  var res = 0; 
  for (var i = 0; i < pole.length; i = i + 2) {
    res += Math.sqrt(pole[i]);
  }
  return res;
}

Pokud tyto dvě funkce spustíte v profileru, zjistíte, že první je rychlejší o 35% až 60%. Je to hezké zrychlení, ale nezapomeňme, že v absolutních číslech je doba vykonávání takovéto funkce při 10 000 opakování zhruba v setinách, maximálně desetinách sekundy. Proto se optimalizace vyplatí pouze pokud programujete velkou aplikaci jako třeba nové mapy. Rozhodně se není třeba ukájet každou miliontinou sekundy, kterou se budete snažit získat optimalizací.

Adresy zpětných odkazů pro tento příspěvek:

Trackback URL (right click and copy shortcut/link location)

4 komentářů

Komentář od: chleba [Návštěvník]
chlebacoooooovece ... to se mi libi jaxviň :)
12. 08. 10 @ 09:55
Komentář od: Jan Kodera [Návštěvník]
Jan KoderaJá myslím, že by fungovalo i rozbalení cyklu. Tj že se v každém kroku cyklu provede více než jeden krok.

function makej(pole) {
var i,
res = 0,
sqrt = Math.sqrt,
len = pole.length;

for ( )
res += sqrt(pole[i]);
res += sqrt(pole[i+2]);
return res;
}
Což ale potřebuje kontrolu sudé velikosti pole. Nicméně pokud je, tak to zrychluje. (Možná to JS engine dělá sám, nevím, sám používám GWT a tak se o čisté JS moc starat nemusím :) ) V tom for cyklu se iterátor musí zvedat o 4, ale systém komentářu mi to nechtěl pustit, tak je for prázdný.
13. 08. 10 @ 14:48
Komentář od: aichi [Člen] E-mail
aichiDíky za komentář. jestli jsi chtěl zadat toto:
for (i = 0; i < len; i = i+4)

tak je třeba mít menšítko napsané entitou.
13. 08. 10 @ 15:20
Komentář od: WuDo [Návštěvník]
WuDoČlánek dobrý a v tomto je dost poučná kniha Umění Programování....

To aichi: ten for cyklus by měl být drobet jinak, resp. jeho délka:
len = pole.length-2;
13. 08. 10 @ 23:57

Napsat komentář


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

Adresa Vašich WWW stránek bude zveřejněna.
(Konce řádku budou převedeny na <br />)
(Jméno, email a webová stránka)
(Dovolí ostatním uživatelům kontaktovat Vás prostřednictvím formuláře pro zprávy (Vaše e-mailová adresa NEBUDE zveřejněna.))