Programim dhe zhvillim, javascript, python, php, html

Në javascript, a është qasja në 'window.Math' më e ngadaltë apo më e shpejtë sesa qasja në objektin 'Math' pa 'dritare'?

Jam disi kurioz se cila është praktika më e mirë kur i referohemi hapësirës së emrave 'globale' në javascript, e cila është thjesht një shkurtore për objektin window (ose anasjelltas në varësi të mënyrës se si e shikoni atë).

Dua të di nëse:

var answer = Math.floor(value);

është më mirë apo më keq se:

var answer = window.Math.floor(value);

A është një më i mirë apo më i keq, qoftë edhe pak, për performancën, përdorimin e burimeve ose përputhshmërinë?

A ka një kosto më të vogël? (Diçka si një tregues shtesë ose diçka tjetër)

Shënim redaktimi: Ndërkohë që në shumicën e situatave jam i lexueshëm ndaj performancës, në këtë rast po injoroj ndryshimet në lexueshmëri për t'u fokusuar vetëm te performanca.


  • Pse ka rendesi? Cili është problemi që po përpiqeni të zgjidhni? 24.01.2010
  • mirë, jam duke optimizuar për performancën, kështu që jam kurioz se cili është më i shpejtë. Nëse bëj mijëra llogaritje, një më pak referencë treguese për lak, ndoshta do të më ndihmojë. 24.01.2010
  • Nuk është një pyetje e vërtetë? Kjo është një pyetje e mirë. 24.01.2010

Përgjigjet:


1

Para së gjithash, mos i krahasoni kurrë gjëra të tilla për arsye të performancës. Math.round është padyshim më e lehtë për sytë sesa window.Math.round, dhe nuk do të shihni një rritje të dukshme të performancës duke përdorur njërën ose tjetrën. Pra, mos e turbulloni kodin tuaj për rritje shumë të lehta të performancës.

Megjithatë, nëse jeni thjesht kurioz se cili është më i shpejtë... Nuk jam i sigurt se si shikohet shtrirja globale "nën kapuç", por do të hamendësoja se qasja në window është njësoj si qasja në Math (window dhe Math jetojnë në të njëjtin nivel, siç dëshmohet nga window.window.window.Math.round duke punuar). Kështu, qasja në window.Math do të ishte më e ngadaltë.

Gjithashtu, mënyra se si shihen variablat lart, do të shihni një rritje të performancës duke bërë var round = Math.round; dhe duke thirrur round(1.23), pasi të gjithë emrat shikohen fillimisht në shtrirjen aktuale lokale, pastaj shtrirjen mbi atë aktual, dhe kështu me radhë, gjatë gjithë rrugës. deri në shtrirjen globale. Çdo nivel shtrirjeje shton një kosto shumë të vogël.

Por përsëri, mos i bëni këto optimizime nëse nuk jeni të sigurt se do të bëjnë një ndryshim të dukshëm. Kodi i lexueshëm dhe i kuptueshëm është i rëndësishëm që ai të funksionojë ashtu siç duhet, tani dhe në të ardhmen.

Këtu është një profilim i plotë duke përdorur Firebug:

<!DOCTYPE html>
<html>
    <head>
        <title>Benchmark scope lookup</title>
    </head>
    <body>
        <script>
        function bench_window_Math_round() {
            for (var i = 0; i < 100000; i++) {
                window.Math.round(1.23);
            }
        }

        function bench_Math_round() {
            for (var i = 0; i < 100000; i++) {
                Math.round(1.23);
            }
        }

        function bench_round() {
            for (var i = 0, round = Math.round; i < 100000; i++) {
                round(1.23);
            }
        }

        console.log('Profiling will begin in 3 seconds...');
        setTimeout(function () {
            console.profile();
            for (var i = 0; i < 10; i++) {
                bench_window_Math_round();
                bench_Math_round();
                bench_round();
            }
            console.profileEnd();
        }, 3000);
        </script>
    </body>
</html>

Rezultatet e mia:
Time tregon totalin për 100,000 * 10 telefonata, Avg/Min/Max kohën e shfaqjes për 100,000 telefonata.

Calls  Percent  Own Time   Time       Avg        Min        Max
bench_window_Math_round
10     86.36%   1114.73ms  1114.73ms  111.473ms  110.827ms  114.018ms   
bench_Math_round
10      8.21%    106.04ms   106.04ms   10.604ms   10.252ms   13.446ms   
bench_round
10      5.43%     70.08ms    70.08ms    7.008ms    6.884ms    7.092ms

Siç mund ta shihni, window.Math është një ide vërtet e keqe. Mendoj se qasja në objektin global window shton shpenzime shtesë. Megjithatë, ndryshimi midis aksesimit të objektit Math nga shtrirja globale dhe thjesht aksesit të një ndryshoreje lokale me referencë në funksionin Math.round nuk është shumë i madh... Mbani në mend se kjo është 100,000 thirrje, dhe diferenca është vetëm 3.6 Znj. Edhe me një milion telefonata do të shihni vetëm një ndryshim prej 36 ms.

Gjërat për të menduar me kodin e mësipërm të profilizimit:

  • Funksionet në fakt shikohen nga një fushë tjetër, e cila shton shpenzimet e përgjithshme (mezi vihet re, megjithatë, unë u përpoqa t'i importoja funksionet në funksionin anonim).
  • Funksioni aktual Math.round shton shpenzimet e larta (po hamendësoj rreth 6 ms në 100,000 thirrje).
23.01.2010
  • +1 për dhënien e përdorimit tim të var round = Math.round disa vlefshmëri. 24.01.2010
  • punë e mirë, keni bërë një punë të shkëlqyer me standardet. Uroj që të mund t'ju jap një +2 24.01.2010
  • Kohët e fundit kam kryer një test dhe ruajtja në memorie var sin = Math.sin shkaktoi një rënie të performancës. Ndoshta nuk njihet më si një funksion që zbatohet në x86 në mënyrë origjinale? 13.04.2013
  • @JanDvorak sin është më i rëndë se round, kështu që ka të ngjarë që shpenzimi shumë i vogël i shkaktuar nga kërkimi shtesë Math është aq i papërfillshëm sa nuk do të jeni në gjendje të matni ndryshimin midis rastësisë. Megjithatë, ekzekutimi aktual i funksionit nuk do të ndryshojë, pasi ka vetëm një zbatim. 16.04.2013
  • Oh dhe siç thashë në përgjigje, ky është një optimizim i vogël: nuk do të ndihmojë asnjë program atje pasi do t'ju duhet të bëni miliona telefonata për të kursyer disa milisekonda. Nëse dëshironi të optimizoni kodin duke përdorur Math.sin, Google për tabelën e kërkimit sinus. 16.04.2013

  • 2

    Kjo mund të jetë një pyetje me interes nëse doni të dini se si Zinxhiri i fushëveprimit dhe Procesi i Rezolucionit të Identifikimit funksionon.

    Zinxhiri i shtrirjes është një listë e objekteve që kërkohen kur vlerësohet një identifikues, ato objekte nuk janë të aksesueshme me kod, vetëm vetitë e tij (identifikuesit) mund të aksesohen.

    Në fillim, në kodin global, zinxhiri i fushëveprimit krijohet dhe inicializohet që të përmbajë vetëm objektin global.

    Objektet pasuese në zinxhir krijohen kur futni në kontekstin e ekzekutimit të funksionit dhe nga deklarata with dhe klauzola catch, të dyja gjithashtu futin objekte në zinxhir.

    Për shembull:

    // global code
    var var1 = 1, var2 = 2;
    (function () { // one
      var var3 = 3;
      (function () { // two
        var var4 = 4;
    
        with ({var5: 5}) { // three
          alert(var1);
        }
      })();
    })();
    

    Në kodin e mësipërm, zinxhiri i fushëveprimit do të përmbajë objekte të ndryshme në nivele të ndryshme, për shembull, në nivelin më të ulët, brenda deklaratës with, nëse përdorni variablat var1 ose var2, zinxhiri i fushës do të përmbajë 4 objekte që do të nevojiten për të inspektoni për të marrë atë identifikues: atë të prezantuar nga deklarata with, dy funksionet dhe në fund objekti global.

    Ju gjithashtu duhet të dini se window është vetëm një veti që ekziston në objektin global dhe tregon vetë objektin global. window prezantohet nga shfletuesit dhe në mjedise të tjera shpesh nuk është i disponueshëm.

    Si përfundim, kur përdorni window, meqenëse është thjesht një identifikues (nuk është fjalë e rezervuar apo diçka e tillë) dhe duhet të kalojë të gjithë procesin e zgjidhjes për të marrë objektin global, window.Math ka nevojë për një hap shtesë që bëhet. nga aksesori i pronës me pikë (.).

    24.01.2010

    3

    Performanca e JS ndryshon gjerësisht nga shfletuesi në shfletues.

    Këshilla ime: benchmark atë. Thjesht vendoseni atë në një lak për, lëreni të funksionojë disa milionë herë dhe caktojeni kohën... shikoni se çfarë merrni. Sigurohuni që të ndani rezultatet tuaja!

    23.01.2010

    4

    (Siç e keni thënë) Math.floor ndoshta do të jetë thjesht një shkurtore për window.Math (pasi window është një objekt global Javascript) në shumicën e implementimeve të Javascript si V8.

    Spidermonkey dhe V8 do të optimizohen aq shumë për përdorim të zakonshëm sa nuk duhet të jetë shqetësues.

    Për lexueshmëri, preferenca ime do të ishte përdorimi i Math.floor, ndryshimi në shpejtësi do të jetë aq i parëndësishëm sa nuk ia vlen të shqetësoheni kurrë. Nëse jeni duke bërë një 100,000 kate, ndoshta është koha për ta hequr atë logjikë nga klienti.

    Ju mund të dëshironi të keni një hundë rreth burimit v8, atje ka disa komente interesante rreth funksioneve të rruajtjes nanosekonda të tilla si kjo int.Parse() një.

    // Some people use parseInt instead of Math.floor.  This
    // optimization makes parseInt on a Smi 12 times faster (60ns
    // vs 800ns).  The following optimization makes parseInt on a
    // non-Smi number 9 times faster (230ns vs 2070ns).  Together
    // they make parseInt on a string 1.4% slower (274ns vs 270ns).
    
    23.01.2010
  • @Mark Yeh, të gjitha përgjigjet vërtetojnë vërtet atë që ju tashmë besoni. 24.01.2010
  • Faleminderit për informacionin shtesë, megjithëse duhet ta kisha formuluar më mirë pyetjen në mënyrë që të fokusohej më shumë në pjesën e performancës dhe më pak në dritare. shënimi +1. 24.01.2010

  • 5

    Me sa kuptoj logjikën e JavaScript, gjithçka që ju referoheni si something kërkohet në sferën e ndryshores globale. Në implementimet e shfletuesit, objekti window është objekti global. Prandaj, kur kërkoni window.Math, në fakt duhet të çreferenconi se çfarë do të thotë window, pastaj të merrni vetitë e tij dhe të gjeni Math atje. Nëse thjesht kërkoni Math, vendi i parë ku kërkohet është objekti global.

    Pra, po- thirrja e Math.something do të jetë më e shpejtë se window.Math.something.

    D. Crockeford flet për këtë në leksionin e tij http://video.yahoo.com/watch/111593/1710507, me sa më kujtohet, është në pjesën e tretë të videos.

    24.01.2010

    6

    Nëse Math.round() thirret në një fushë lokale/funksioni, përkthyesi do të duhet të kontrollojë fillimisht për një var lokal pastaj në hapësirën globale/dritare. Pra, në shtrirjen lokale supozimi im do të ishte se window.Math.round() do të ishte shumë pak më i shpejtë. Ky nuk është montim, ose C ose C++, kështu që nuk do të shqetësohesha se cili është më i shpejtë për arsye performance, por nëse për kuriozitet, sigurisht, shënojeni atë.

    23.01.2010
  • window.Math.round() do të duhet ende të kërkojë një ndryshore lokale window. 24.01.2010
  • Materiale të reja

    Masterclass Coroutines: Kapitulli-3: Anulimi i korutinave dhe trajtimi i përjashtimeve.
    Mirë se vini në udhëzuesin gjithëpërfshirës mbi Kotlin Coroutines! Në këtë seri artikujsh, unë do t'ju çoj në një udhëtim magjepsës, duke filluar nga bazat dhe gradualisht duke u thelluar në..

    Faketojeni derisa ta arrini me të dhënat false
    A e gjeni ndonjëherë veten duke ndërtuar një aplikacion të ri dhe keni nevojë për të dhëna testimi që duken dhe duken më realiste ose një grup i madh të dhënash për performancën e ngarkesës...

    Si të përdorni kërkesën API në Python
    Kërkesë API në GitHub për të marrë depot e përdoruesve duke përdorur Python. Në këtë artikull, unë shpjegoj procesin hap pas hapi për të trajtuar një kërkesë API për të marrë të dhëna nga..

    Një udhëzues hap pas hapi për të zotëruar React
    Në këtë artikull, do të mësoni se si të krijoni aplikacionin React, do të mësoni se si funksionon React dhe konceptet thelbësore që duhet të dini për të ndërtuar aplikacione React. Learning..

    AI dhe Psikologjia — Pjesa 2
    Në pjesën 2 të serisë sonë të AI dhe Psikologji ne diskutojmë se si makineritë mbledhin dhe përpunojnë të dhëna për të mësuar emocione dhe ndjenja të ndryshme në mendjen e njeriut, duke ndihmuar..

    Esencialet e punës ditore të kodit tim VS
    Shtesat e mia të preferuara - Git Graph 💹 Kjo shtesë është vërtet e mahnitshme, e përdor përpara se të filloj të punoj për të kontrolluar dy herë ndryshimet dhe degët më të fundit, mund të..

    Pse Python? Zbulimi i fuqisë së gjithanshme të një gjiganti programues
    Në peizazhin gjithnjë në zhvillim të gjuhëve të programimit, Python është shfaqur si një forcë dominuese. Rritja e tij meteorike nuk është rastësi. Joshja e Python qëndron në thjeshtësinë,..