SFATURI -> PERFORMANTE JAVASCRIPT

Aici postaţi orice este legat de tehnologiile "client side". HTML, HTML5, XHTML, CSS, CSS3, XML, Standarde
Manual JS: http://www.phpromania.net/jsmanual/index.html

Moderatori: eyecon, Moderatori

LXS
Senior Member
Mesaje: 375
Membru din: Dum Oct 05, 2008 8:34 pm
Localitate: Timisoara
Contact:

SFATURI -> PERFORMANTE JAVASCRIPT

Mesajde LXS » Lun Aug 01, 2011 10:00 pm

Avand in vedere ca tot mai multe persoane incep sa foloseasca canvas, pentru a scrie motoare de jocuri sau rendere 3D, avand nevoie de o multime de iteratii, ceea ce insemnand ca calculatorul foloseste la maxim resursele lui in cantitati foarte mari, si am ajuns la concluzia prin o multime de teste ca acest articol de sfaturi ar scade acest procent de resurse folosite cu pana la 60%, sau poate chiar mai mult.
Aceste sfaturi vin si de ajutor persoanelor care detin un website "heavily scripted", pentru a ajunge la ideea ca nu toti utilizatorii website-ului au un sistem puternic.

Primul sfat -> Nu folositi "with"
Imaginati-va ca browserul este ca un animal de companie, si "with" (cu), este ca si cand l-am lovi in ochi. Nui asa ca nu ar fi frumos sa facem asta?
Asa ca nu folositi:

Cod: Selectaţi tot

var obiecte = {pixuri:5, creioane:2, caiete:10};

with (obiecte) {

pixuri = 7;

}


Folositi asta in schimb:

Cod: Selectaţi tot

var obiecte = {pixuri:5, creioane:2, caiete:10};

obiecte.pixuri = 7;


Al doilea sfat -> Pentru a salva putina memorie
In loc de asta:

Cod: Selectaţi tot

obiect = new Object();
obiect.x = "valoare";
obiect.y = "valoare";
obiect.z = 1;


Folositi asta:

Cod: Selectaţi tot

obiect = {
x: "valoare",
y: "valoare",
z: 1
}


Al treilea sfat -> Functiile Math pot fi putin cam lente, iar Math.floor este una dintre cele mai utilizate functii
Normal a-ti face asa:

Cod: Selectaţi tot

var zecimal = 1.2;
var testZecimal = Math.floor(zecimal);


Dar, în loc, acest lucru este mai rapid pe fiecare browser cu excepţia Chrome-ului (este destul sa folosim functia standard deoarece este destul de rapida, nu este necesar sa facem teste deoarece functia standard utilizata cu chrome nu este semnificativ mai lenta decat varianta de ma jos, in schimb viteza este cu mult mai mare in alte browsere).

Cod: Selectaţi tot

var zecimal = 1.2;
var testZecimal = ~~(1 *zecimal);


Al patrulea sfat -> Iteratiile sunt rapide, dar multiple declaratii sunt mai rapide
Iteratie normala:

Cod: Selectaţi tot

var a = 0;
for (var b = 1; b < 1000; b++) {
a++;
}


Declaratiile multiple (da, acestea sunt mult mai rapide dar arata teribil in cod… dar daca perfomanta conteaza mai mult, atunci aceasta ar fi calea):

Cod: Selectaţi tot

a++; a++; a++; a++; a++; a++; ...


Al cincilea sfat -> Numaratoarea descrescatoare este mai rapida decat numaratoarea crescatoare
Iteratie normala:

Cod: Selectaţi tot

for (var a = 0; a < 1000; a++) {
// Ceva
}


Numaratoare descrescatoare:

Cod: Selectaţi tot

var a = 1000;
 
while (a--) {
// Ceva
}


Pentru o numaratoare si mai rapida folositi do while.

Al saselea sfat -> Forma scurta de parcurgere a elementelor fara a le stii lungimea
In loc de asta:

Cod: Selectaţi tot

var radacinaLista = document.getElementById("tr");
for(var a=0; a>radacinaLista.length; a++){
var radacina = radacinaLista[a];
}


Folositi asta:

Cod: Selectaţi tot

for(var a=0; radacina=document.getElementById("tr")[a]; a++){
// Ceva
}

Nu se citeste lungimea la fiecare iteratie, si este mai rapid din punct de vedere al performantei.

Al saptelea sfat -> Reducerea cautarilor in iteratii
In loc de asta:

Cod: Selectaţi tot

for (var a = 0; a < unObiectSauMatrice.length; a++)


Folositi asta:

Cod: Selectaţi tot

for (var a = 0, b = unObiectSauMatrice.length; a < b; a++)


Aceasta functioneaza mai rapid deoarece in loc sa evalueze lungimea fiecarui obiect sau a unei matrici la fiecare iteratie in parte, ceea ce insemnand ca la fiecare iteratie in parte se va accesa obiectul si va primi raspuns (in acest caz lungimea), asa ca lungimea este accesata o singura data si este salvata in "b", apoi "b" va fi evaluat inaintea lui "a" la fiecare iteratie.

Al optulea sfat -> Reducerea accesului la proprietatile obiectului
In loc de asta:

Cod: Selectaţi tot

var obiecte = {continut: {material: {lemn: 1}}};
 
obiecte.continut.material.lemn = 1;
if (obiecte.continut.material.lemn > 0) {
alert(obiecte.continut.material.lemn);
}


Folositi asta:

Cod: Selectaţi tot

var obiecte = {continut: {material: {lemn: 1}}};
 
obiecte.continut.material.lemn = 1;
var temporarLemn = obiecte.continut.material.lemn;
if (temporarLemn > 0) {
alert(temporarLemn);
}


Aceasta functioneaza mai rapid deoarece dupa ce valoarea este setata pentru "obiecte.continut.material.lemn", nu este nevoie de a pastra accesarea continutului obiectului, apoi materialul obiectului va fi doar pentru a accesa valoarea lemnului. In schimb am stocat o variabila locala cu valoarea lemnului astfel va fi evaluata mult mai rapid.

Al noualea sfat -> Setati valoriile variabilelor in interiorul unei declaratii
In loc de asta:

Cod: Selectaţi tot

var a = true;
var b = false;
 
if (a) {
b = true;
}


Folositi asta:

Cod: Selectaţi tot

var a = true;
var b = false;
 
if (a && b = true) {}


Puteti de asemenea sa actionati atribuirea variabilei cu un test pe false:

Cod: Selectaţi tot

if (a || b = true) {}


Nu arata prea bine acestea dar in schimbul performantei merita folosita aceasta metoda.

Al zecelea sfat -> Atunci cand scrieti cod, declarati intotdeauna variabilele cu o valoare initiala
In loc de asta:

Cod: Selectaţi tot

n = true;


Folositi asta:

Cod: Selectaţi tot

var n = true;

(Asta daca nu a-ti declarat-o deja mai devreme sau daca nu accesati o variabia globala).

Al unsprezecelea sfat -> Utilizati dispozitivul lui Duff
Nu o sa incep sa explic aici acest articol, exista unul pe wikipedia http://en.wikipedia.org/wiki/Duff&#8217;s_device si daca sunteti inca pierduti folositi noul minunat motor de cautare, denumit Google. :D

Al doisprezecelea sfat -> Invatati JavaScript citind specificatiile lui ECMAScript
A invata sa programam in JavaScript este foarte usor. A invata sa programam in JavaScript este ca o forma de arta, si manualul ar formei de arta este ECMAScript: http://www.ecma-international.org/publi ... ma-262.htm

DE RETINUT!
*In cele mai multe cazuri operatiile pe biti in javascript sunt mai rapide decat functiile Math standard.
*In javascript comparand un numar cu 0, este mult mai rapid decat comparand cu un oricare alt numar.
*Structura if/else, este mai lenta decat structura switch.
*Pentru anumite operatii Math de conversie putem sa generam noi tabelele este cu pana la de 2 ori mai rapid decat standard.

Bibliografie:
http://www.ecma-international.org
http://www.blog.andyhume.net
http://www.isogenicengine.com
http://en.wikipedia.org/wiki/Duff&#8217;s_device

Luat din mai multe parti, tradus si modificat.
Va rog sa postati si alte sfaturi cine mai cunoaste.
Multumesc!
Ultima oară modificat Joi Sep 22, 2011 5:27 am de către LXS, modificat 1 dată în total.



Avatar utilizator
Birkoff
Senior Member
Mesaje: 6380
Membru din: Joi Mar 18, 2004 2:34 pm
Localitate: Bucuresti
Contact:

Mesajde Birkoff » Lun Aug 01, 2011 10:37 pm

am editat eu titlul si l-am trecut ca important ca sigur o sa mai apara si alte sugestii (la fel cum e in sectiunea php topicul trips and trics) si e bine sa stie toti de ele.
1) CMS, ERP, CRM, etc... (doar pentru clienti))
2) Portofoliu, servicii, contact, blog
3) Folositi aceasta clasa sql in proiectele voastre (open source)
4) Vrei un magazin virtual la cheie, usor de folosit, cu api-uri incluse pentru maximizarea vanzarilor si multe alte facilitati? Da un semn si discutam.

LXS
Senior Member
Mesaje: 375
Membru din: Dum Oct 05, 2008 8:34 pm
Localitate: Timisoara
Contact:

Mesajde LXS » Mar Aug 02, 2011 3:23 am

Dupa sfaturile de mai sus, cateva cunostinte javascript, si multe batai de cap, ati putea sa va creati propriul joc incepand de la acest engine 2D, foarte simplu si este explicat in detaliu fiecare linie de cod. Adaugand si Node.js ar iesi un multiplayer grozav.

http://www.brighthub.com/hubfolio/matth ... ement.aspx

dechim
Senior Member
Mesaje: 1486
Membru din: Mar Mai 10, 2005 11:53 pm
Localitate: Drobeta Turnu Severin

Mesajde dechim » Mar Aug 02, 2011 3:36 am

Eu nu inteleg 'Primul sfat -> Nu folositi "with"''
De ce? Nu e mai rapid codul

Cod: Selectaţi tot

with (obiecte) {
  prop1 = 7;
  prop2 = 'antet';
  prop3 = 'a';
  prop4 = 5;
  prop5 = 11;
}

decat uratul:

Cod: Selectaţi tot

  obiecte.prop1 = 7;
  obiecte.prop2 = 'antet';
  obiecte.prop3 = 'a';
  obiecte.prop4 = 5;
  obiecte.prop5 = 11;

Daca exista o cale mai lunga
obj1.obj2.obj3.obj4.prop1 = val;
sunt convins ca se descurca mult mai usor daca folosesc "with"
Ma gandesc ca nu trebuie de fiecare data sa identifice lantul de obiecte pentru a atribui o valoare unei proprietati. Daca e vorba de una singura (proprietate) atunci da! Nu fac bloc pentru o singura atribuire.
:)
Imi place motivatia:
Imaginati-va ca browserul este ca un animal de companie, si "with" (cu), este ca si cand l-am lovi in ochi. Nui asa ca nu ar fi frumos sa facem asta?

nevvermind
Senior Member
Mesaje: 1264
Membru din: Mar Iun 22, 2010 3:17 pm

Mesajde nevvermind » Mar Aug 02, 2011 8:20 am

"Imaginati-va ca browserul este ca un animal de companie, si "with" (cu), este ca si cand l-am lovi in ochi. Nui asa ca nu ar fi frumos sa facem asta?"

Cel mai amuzant ad misericordiam pe care l-am citit vreodata!

LXS
Senior Member
Mesaje: 375
Membru din: Dum Oct 05, 2008 8:34 pm
Localitate: Timisoara
Contact:

BENCHMARK

Mesajde LXS » Mar Aug 02, 2011 10:09 am

@dechim:
Uite diferenta:
(with) la 1 milion de iteratii, a cate 15 rezultate individuale si facuta o medie.

CHROME:
37.33 ms
12.44 ms

IE 8:
216.33 ms
214.72 ms


Am facut o analiza de viteza pentru toate sfaturile (care pot fi testate), si am inceput cu 1 milon de iteratii. Unde timpul de procesare era foarte mic am lasat 1 milion unde era foarte mare am redus pana la zece mii (mai ales pentru IE 8, care da des script execution). Rezultatele sunt pentru 1 milion de iteratii cu fiecare bucata de cod in parte, apoi am multiplicat sau divizat timpul cu cat am redus sau am crescut numarul iteratiilor).

Exemplu:
10 milioane iteratii factor de divizare al tumpului cu 10.
1 milion iteratii factor de multiplicare al timpului cu 1.
100 000 iteratii factor de multiplicare al timpului cu 10.
10 000 iteratii factor de multiplicare al timpului cu 100.
s.a.m.d

Sfat 1:
CHROME:
37.33 ms
12.44 ms
(o crestere de performanta foarte ridicata)

IE 8:
216.33 ms
214.72 ms
(o crestere de performanta foarte mica)

Sfat 2:
CHROME:
5.67 ms
5.32 ms
(o mica scadere de performanta)

IE 8:
(apare des "stop script execution") 244.23 ms
182.34 ms
(o crestere de performanta foarte ridicata)

Sfat 3:
CHROME:
2.35 ms
(ciudat) (am testat asta din nou manual dar toate testele trec de 2.35 ms) 2.73 ms
(mai bine este folosita functia standard de rotunjire in chrome)
(o foarte mica scadere de performanta)

IE 8:
83.46 ms
56.32 ms
(crestere de performanta)

Sfat 4:
CHROME:
1472.56 ms
1.77 ms
(o crestere de performanta de neegalat)

IE 8:
314125.93 ms
9.36 ms
(o crestere de performanta de neegalat)

Sfat 5:
CHROME:
824.84 ms
706.22 ms

IE 8:
20323.89 ms
11308.20 ms
(o dublare de performanta)

Sfat 6:
CHROME:
??? ms

IE 8:
??? ms

Sfat 7:
CHROME:
13.71 ms
(ciudat) (am testat asta din nou manual dar toate testele trec de 21 ms) 21.54 ms
(o scadere de performanta radicala)

IE 8:
(apare des stop script execution) 272.65 ms
(aici functioneaza mai bine) (dar apare des stop script execution) 218.32 ms

Sfat 8:
CHROME:
226.37 ms
252.45 ms

IE 8:
5321.31 ms
5794.78 ms

Sfat 9:
CHROME:
14.64ms
??? ms

IE 8:
63.98 ms
??? ms

Toate codurile au fost verificate cu acest script:

Cod: Selectaţi tot

<html>
<head>
<title>JS BENCHMARK</title>
<script type="text/javascript">
var start=(new Date).getTime();

for(var a=0;a<=1000000;a++)
{
// Bloc de cod
//     JS
}

var res=(new Date).getTime() - start;

function print()
{
   return document.getElementById("speed").innerHTML=res/10+" ms";
}
</script>
</head>
<body onload="print();">
<span id="speed">s</span>
</body>
</html>


Aceste teste pot avea o marja de eroare de +/-10%. Si au fost facute cu toate programele oprite, pentru a evita fluctuatia de performanta a calculatorului.
Ultima oară modificat Mar Aug 02, 2011 8:04 pm de către LXS, modificat 1 dată în total.

dechim
Senior Member
Mesaje: 1486
Membru din: Mar Mai 10, 2005 11:53 pm
Localitate: Drobeta Turnu Severin

Mesajde dechim » Mar Aug 02, 2011 12:10 pm

Codul testat de la sfatul 1 este cel din post?
Pentru ca nimeni nu foloseste "with"pentru o singura atribuire.

[EDIT]
Nu sunt incapatanat si nu o tin pe a mea - inca nu sunt convins

dechim
Senior Member
Mesaje: 1486
Membru din: Mar Mai 10, 2005 11:53 pm
Localitate: Drobeta Turnu Severin

Mesajde dechim » Mar Aug 02, 2011 1:04 pm

Am testat cu 100 000 de iteratii 20 de atribuiri in bucla

with VS attribuire simpla

IE8
45.9 ms VS 52.5 ms

FireFox (zdrobitor)
99 ms VS 0.4 ms

IE8 adesea se opreste si ma avertizeaza in bucla fara "with":
"A script on this page is causing your web browser to run slowly. If it continues to run, your computer might become unresponsive."
Deci un script de genul celui de mai sus fara "with"nici nu ar functiona corect pe IE8.

Raman la convingerea mea, "with" trebuie folosit in scopul pentru care a fost introdus in limbaj.
Daca am multe accesari de genul :
obj1.obj2.obj3.obj4.properties
un
with (obj1.obj2.obj3.obj4)
urmat de peste 5 accesari ale metodelor sau proprietatilor obiectului obj4, este exact ce-i trebuie interpretorului din browser ca sa nu reidentifice de fiecare data obiectul in memorie.

*** FireFox e prost, nu are implementat corect "with"
*** exista o limita de la care "with" devine performant fata de atribuirile obisnuite.

Sfatul tau ramane in picioare avand in vedere exmplul pe care l-ai dat, o singura atribuire (dar nu pentru una a fost introdus with).

Avatar utilizator
Birkoff
Senior Member
Mesaje: 6380
Membru din: Joi Mar 18, 2004 2:34 pm
Localitate: Bucuresti
Contact:

Mesajde Birkoff » Mar Aug 02, 2011 2:38 pm

LXS trebuia sa specifici si pe ce procesor ai testat... de preferat e sa se testeze pe procesoare atom (cele mai slabe) ca sa se vada cum functioneaza pe sisteme slabe cum ar fi tablete sau telefoane... pe sisteme normale oricum procesorul e mult mai puternic...
1) CMS, ERP, CRM, etc... (doar pentru clienti))
2) Portofoliu, servicii, contact, blog
3) Folositi aceasta clasa sql in proiectele voastre (open source)
4) Vrei un magazin virtual la cheie, usor de folosit, cu api-uri incluse pentru maximizarea vanzarilor si multe alte facilitati? Da un semn si discutam.

LXS
Senior Member
Mesaje: 375
Membru din: Dum Oct 05, 2008 8:34 pm
Localitate: Timisoara
Contact:

Mesajde LXS » Mar Aug 02, 2011 8:15 pm

@dechim
Da am testat doar cu o singura atribuire.


@birkoff
Am testat doar cu configuratia sistemului meu.
Dual-core Intel E5300 @2.60Ghz 2.59Ghz
4.00 GB RAM

dechim
Senior Member
Mesaje: 1486
Membru din: Mar Mai 10, 2005 11:53 pm
Localitate: Drobeta Turnu Severin

Mesajde dechim » Mar Aug 02, 2011 9:57 pm

@LXS, la "Al saselea sfat -> Forma scurta de parcurgere a elementelor fara a le stii lungimea" nu m-as fi gandit vreodata. Frumos si ca tehnica de programare.

[offtopic]
Chiar se invata pe forumul asta si nu numai programare - @nevvermind multumesc pentru "ad misericordiam", nu cunosteam termenul, asta era azi la 2:30 AM iar acum sunt mai destept datorita tie.

Avatar utilizator
socu
Senior Member
Mesaje: 470
Membru din: Mie Apr 22, 2009 11:05 pm
Localitate: Marghita

Mesajde socu » Mie Aug 03, 2011 11:51 am

La sfatul 2 cum salvam memoria?
La 4 este o exagerare sa punem 1000 de instructiuni cand le putem pune intr-un for. (calea ar fi a+=999 nu a++ de 999 de ori)
La 5 ai facut un for ca exemplu negativ si ai dat ca exemplu pozitiv un while. Da ce, in for nu poti pune --? Aiurea iar, mai ales ca de cele mai multe ori trebuie sa mergi crescator.
La 7 lungimea aia nu cred ca se evalueaza ci se ia direct.
La 8 nu bine am "salvat" memoria la pasul 2 ca deja o irosim cu o variabila temporara.
La 9 exemplul if (a || b = true) {} nu stiu la ce anume se refera dar are efect total diferit de if (a && b = true) {}.
La 10 luand textul tau: "Atunci cand scrieti cod, declarati intotdeauna variabilele cu o valoare initiala" exemplul ar trebui sa fie:
Nu: var n;
Da: var n = true;
La 11 pacat ca nu ai un exemplu in js pentru cei "pierduti". Eu il astept.

dechim
Senior Member
Mesaje: 1486
Membru din: Mar Mai 10, 2005 11:53 pm
Localitate: Drobeta Turnu Severin

Mesajde dechim » Joi Aug 04, 2011 3:50 am

La 7 asa e, length se ia de undeva.
Pentru obiectul String, de exemplu, length este o proprietate, deci valoarea exista dar o citeste mai incet decai valoarea unei variabile simple. Am facut testul si LXS are dreptate.

Si la 4 are dreptate, am testat cu 10 iteratii pe care le-am repetat intr-un for de 10000 de ori si exista diferenta intre timpii de executie. In practica nu se intalnesc atatea dar adunate de la multe scripturi probabil conteaza.
Am constatat ca la prima rulare diferenta este mai mare dar la refresh repetat se micsoreaza (pe IE).

LXS
Senior Member
Mesaje: 375
Membru din: Dum Oct 05, 2008 8:34 pm
Localitate: Timisoara
Contact:

raspuns si exemple

Mesajde LXS » Joi Aug 04, 2011 9:20 am

@socu
La sfatul 2 cum salvam memoria?
La 4 este o exagerare sa punem 1000 de instructiuni cand le putem pune intr-un for. (calea ar fi a+=999 nu a++ de 999 de ori)
La 5 ai facut un for ca exemplu negativ si ai dat ca exemplu pozitiv un while. Da ce, in for nu poti pune --? Aiurea iar, mai ales ca de cele mai multe ori trebuie sa mergi crescator.
La 7 lungimea aia nu cred ca se evalueaza ci se ia direct.
La 8 nu bine am "salvat" memoria la pasul 2 ca deja o irosim cu o variabila temporara.
La 9 exemplul if (a || b = true) {} nu stiu la ce anume se refera dar are efect total diferit de if (a && b = true) {}.
La 10 luand textul tau: "Atunci cand scrieti cod, declarati intotdeauna variabilele cu o valoare initiala" exemplul ar trebui sa fie:
Nu: var n;
Da: var n = true;
La 11 pacat ca nu ai un exemplu in js pentru cei "pierduti". Eu il astept.


La sfatul 2 -> Nu am cum sa testez asta, dar dupa parerea mea salveaza pentru ca nu mai creeaza obiectul ci il incarca...? (as vrea sa fac un test de memorie dar nu stiu cum, poate ma ajuti tu :D) Si in plus este o forma mai scurta.
La sfatul 4 -> Fa un test am atasat codul de benchmark.
La sfatul 5 -> Este o comparatie intre numaratoarea crescaroare respectiv descrescatoare (si cu un --var in for), ruleaza mai rapid.
La sfatul 7 -> Acolo este o problema des intalnita, majoritatea care scriu cod js nu mai fac o variabia speciala care sa citeasca lungimea ci o introduc direct in expresia for-ului ceea ce este foarte GRESIT (sfat 4 primul exemplu). Conceptul de rulare ar fi urmator:

In loc de asta:
for (var a = 0; a < unObiectSauMatrice.length; a++)

Browser-ul interpreteaza, for(expr1; expr2; expr3), expresia1 o variabila a definita ca avand valoare 0 (start).
La fiecare iteratie for-ul va arata asa for ((ignored); 0++ < (check) unObiectSauMatrice.length; a++), incrementeaza a pana ajunge ca expresia 2 sa returneze fals (atunci for-ul este complet/terminat). Dar in schimb greseala care este? La fiecare iteratie in parte se va citi lungimea unui obiect/matrice!

Folositi asta:
for (var a = 0, b = unObiectSauMatrice.length; a < b; a++)

La fiecare iteratie for-ul va arata asa for ((ignored); 0++ < (known lenght); a++), incrementeaza a pana ajunge ca expresia 2 sa returneze fals (atunci for-ul este complet/terminat). Chestia este ca la fiecare iteratie in parte nu o sa mai verifice lungimea. (printr-un test ai fi vazut diferenta).

Si de ce este "ignored" prima expresie? Ea este folosita doar pentru prima iteratie ca interpretorul javascript sa stie de unde incepe iteratia.

La sfatul 8 -> Foarte logic iroesti putina memorie in schimbul vitezei. Stochez in variabila calea catre acea valoare, nu de fiecare data cand am nevoie de valoarea respectiva sa scriu calea "Minimise access to object properties". (--memory, ++speed)
La sfatul 9 -> Da 2 exemple total diferite (pentru 2 conditii diferite), "Set variable values inside an if statement", interpretorul va atribui mai rapid valoarea din conditie decat in bucla de cod).
La sfatul 10 -> Nu am explicat bine, m-am referit la faptul ca tot timpul a se folosi var, pentru a fi declarate variabilele globale, nu a le declara cu o valoare initiala, pentru ca poate pe parcurs vom avea nevoie de ea "null type".
La sfatul 11 -> Duff's device, este un mod de a optimiza iteratiile din cod, de fapt este o tehnica C dar poate fi implementata in javascript.

LATER EDIT:
Sfatul 4 apartine lui Duff's device "Loop Unrolling":

Cod: Selectaţi tot

for (var i=0;i<iterations;)
    {
    [do something with i here];i++;
    [do something with i here];i++;
    [do something with i here];i++;
    [do something with i here];i++;
    [do something with i here];i++;
    }


La sfatul 11 un exemplu, tot Duff's device (este mult mai rapid decat un loop normal:

Cod: Selectaţi tot

Here's the code (demonstrating a Duff's Device with the loop unrolled 8 times):


// This is just test stuff to make everything clearer.

testVal=0;

iterations = 5125;

// End test stuff

--------------------------------------------

// Begin actual Duff's Device
// JS Implementation by Jeff Greenberg 2/2001

var n = iterations / 8;
var caseTest = iterations % 8;   

do {

    switch (caseTest)
    {
    case 0:              [Do Something to tesVal here];
    case 7:              [Do Something to tesVal here];
    case 6:              [Do Something to tesVal here];
    case 5:              [Do Something to tesVal here];
    case 4:              [Do Something to tesVal here];
    case 3:              [Do Something to tesVal here];
    case 2:              [Do Something to tesVal here];
    case 1:              [Do Something to tesVal here];
                   
    }
    caseTest=0;

}

while (--n > 0);


Win98 (CEL/366)

NS 4.73 total
normal loop
22360ms
duff loop
1260 ms
NS 4.73 per cycle
.0447 ms .0025 ms

IE 5.5 total
normal loop 770 ms
duff loop 710 ms
IE 5.5 per cycle
.0015 ms .0014 ms

Windows 7
Chrome
normal loop 5 ms
duff loop 2 ms
Chrome per cycle
.00000999 ms 0.00000399 ms

IE 8
normal loop 63 ms
duff loop 22 ms
Chrome per cycle
.00012597 ms .00004399 ms

In cele mai multe cazuri operatiile pe biti in javascript sunt mai rapide decat functiile Math standard.
In javascript comparand un numar cu 0, este mult mai rapid decat comparand cu un oricare alt numar.
Structura if/else, este mai lenta decat structura switch.
Pentru anumite operatii Math de conversie putem sa generam noi tabelele este cu pana la de 2 ori mai rapid decat standard:

Cod: Selectaţi tot

<script language="JavaScript">
 
// Create Lookup Table
 
logTable = new Array(100);
 
for (var i=0; i <=99; i++)
    {
   
    logTable[i] = Math.log(i);
   
    }
 
function logTableTest(iter) {
document.test3.status.value="Testing";
testVar=0;
 
startTime= new Date();
 
for (var k=1; k<=iter; k++) {
 
for (var i=0; i<=99; i++)
    {
    testVar=logTable[i];
   
    }
 
}
 
endTime = new Date();
 
document.test3.tableT.value=endTime-startTime;
document.test3.table.value=(endTime-startTime)/iter;
 
 
}
 
 
function logPlainTest(iter) {
 
testVar=0;
 
startTime= new Date();
 
for (var k=1; k<=iter; k++) {
 
for (var i=0; i<=99; i++)
    {
    testVar=Math.log(i);
   
    }
 
}
endTime = new Date();
 
document.test3.plainT.value=endTime-startTime;
document.test3.plain.value=(endTime-startTime)/iter;
 
document.test3.status.value="Finished";
 
}
 
 
</script>
 
<form name="test3">
<br><input type="button" value="Test" onClick="logTableTest(3500);logPlainTest(3500)">
 status: <input type="text" name="status" size="20">


Si inca cateva sfaturi: http://home.earthlink.net/~kendrasg/inf ... tMain.html

Avatar utilizator
socu
Senior Member
Mesaje: 470
Membru din: Mie Apr 22, 2009 11:05 pm
Localitate: Marghita

Mesajde socu » Joi Aug 04, 2011 10:47 am

La 1 mi se pare normal ca with sa mearga greu. Daca ai codul:

Cod: Selectaţi tot

with(obj) {
  x = 1;
  y = 2;
}

El intai va cauta daca x si y sunt din obj, apoi daca sunt definite undeva altfel banuiesc ca le va initializa.

La 2 daca ii dam {a: 1, b: 2, ...} eu banuiesc ca le parcurge cu un for (sau while) si le adauga la obiect. Ceea ce contrazice sfatul 4.

La 4 inteleg ca este mai optim din punctul de vedere al vitezei, dar daca vrei sa modifici ceva in cod pentru ca ai descoperit un bug sa zicem? Presupune urmatorul cod:

Cod: Selectaţi tot

for(... ; ... ; ...) {
  {set instr
    ...acest set contine 200 de linii
  /set instr}
 
  I++; //incrementarea

   {acelasi set instr
    ...acest set contine (normal) 200 de linii
  /set instr}

 I++;

    {acelasi set instr
    ...acest set contine (normal) 200 de linii
  /set instr}

 I++;

}

Acum daca vrei sa modifici ceva pe linia 73 a setului trebuie sa o faci in fiecare set. Daca vrei sa si adaugi ceva o sa te ia cu draci sa faci in toate. Nu cred ca este un stil de programare recomandat.

La 5 in general while este mai rapid ca for. Chiar daca (si probabil ca asa e) e mai rapid sa mergi descrescator tot nu il consider ca ceva bun.

La 7 daca voi ziceti ca merge mai greu asa o fi. Ideea e ca si obj.length e knnown value ca e o variabila in obj. Problema pare a fi in accesarea de catre js a proprietatilor unui obj. Intr-un limbaj de programare normal NU e gresit asa ceva.

La 9 am ramas tampit cand am vazut ca nu intrerupe verificarea conditiei la 'a' ca intr-un limbaj de programare normal. Daca ai codul:

Cod: Selectaţi tot

if(FALSE && (ceva care da eroare)) {}

atunci nu ar trebui sa intre in (ceva care da eroare) ca in limbajele normale. Vad ca js e mai special, dar in sensul prost. Adica bine ca am si & pe biti ca pana la urma sa aiba efect similar cu &&. Grozav!

Se pare ca js chiar e mai special si incalca ce reguli vrea el.
Ultima oară modificat Joi Sep 08, 2011 11:38 pm de către socu, modificat 1 dată în total.


Înapoi la “HTML/JavaScript/CSS”

Cine este conectat

Utilizatori ce ce navighează pe acest forum: Niciun utilizator înregistrat și 23 vizitatori