Press "Enter" to skip to content

GOTO 2016 • JavaScript Performance Through the Spyglass • Vyacheslav Egorov


il mio nome è ricco amici slavi mi ha chiamato
Slava
tutte le persone sono mie amiche a meno che loro
scrivere JavaScript no in ogni caso, quindi sono qui
per parlare di prestazioni JavaScript e
questo discorso è un po ‘diverso io
guardato il programma e tutti i colloqui sono
principalmente sull’uso di javascript e così via
sono destinati a JavaScript
programmatori ma il mio discorso è un po ‘
dall’altro lato dall’interno della
trincee trasmette la mia prospettiva
Prestazioni JavaScript basate sul mio
esperienza lavorando sul v8 su cui ho lavorato
tutti i tipi di macchine virtuali diverse
nella mia vita a partire da Java VM e I
ha anche lavorato su cose come v8 che è un
Motore JavaScript all’interno di cromo e freccia
VM e GT inferiore anche se questo discorso
si sta concentrando sulla mia esperienza su v8
quindi e perché è importante sapere come
v8 funziona bene perché è tutto MS
sono molto complessi e per capire il
prestazioni di cui hai davvero bisogno
per esempio, come funzionano le VM
questa è una domanda di overflow dello stack da
oggi lo modifica proprio al mattino quindi
qualcuno è molto curioso del perché sul nodo
sedia così quante persone usano nodejs okay
molte di voi le mie condoglianze, quindi perché lo sono
no js ‘let basato su loop è più lento di
ci sono basati per il ciclo di a
una quantità considerevole forse quattro volte
è un ciclo vuoto, quindi perché è il ciclo vuoto
più lento quindi il sovraccarico del ciclo in sé
è considerevolmente più alto e di solito tu
non hanno altra scelta, ma per fare una domanda su
Stack Overflow se incontri il
un problema del genere ma in realtà se tu
sono preparati almeno un po ‘allora
si può avere una scelta si può andare a provare
profilo che cosa fa la macchina virtuale per te
può almeno provare a leggere il codice che
produce così forse il codice il
macchina virtuale stessa se puoi farcela
con C ++ e non nel secchio per
quello e
per esempio, non molte persone possono farcela
il grano ha questo compilatore ottimizzante
chiamato albero motore e se lo si desidera
trattare con albero motore è possibile utilizzare un piccolo
strumento che ho scritto che ti permette di
leggi il codice che genera e
usando questo strumento puoi vedere cosa
succede con quello per loop e it
probabilmente è un po ‘difficile da vedere ma
questo è il codice del punto di riferimento nel
forma del grafico del flusso di controllo che è
usato dal compilatore di ottimizzazione e it
non è davvero ciò che importa davvero
in realtà succede ma puoi vederne un po ‘
cose sospette stanno accadendo perché
hai il loop con quattro fili in alto
lì e in qualche modo c’è un molto
grande anello laggiù che è
considerevolmente più grande e cosa c’è di più
di buon auspicio è che c’è un ciclo
all’interno del ciclo se usi il let
vincolante nel ciclo for questo è davvero
strano
e in realtà sono stati aggiunti gli attacchi guidati
dopo che mi sono già allontanato da v8 così io
ero curioso di sapere cosa fosse in realtà
accadendo e il modo in cui stavo cercando di
risolvere questo non sapevo in realtà cosa
sta succedendo così ho avuto la fonte del
v8 ci sono istruzioni su come ottenerlo
e ho creato una versione di debug della v8
che è molto facile da fare
esempio un linux un po ‘duro
Windows, ma lo sviluppo su Windows è
difficile comunque piangi tutto il tempo e
poi eseguo questa versione passare il test
file ad esso e ho chiesto di stampare il
albero sintattico astratto che costruisce
questo codice e sembra molto gentile
spaventoso non importa ciò che effettivamente
accadendo lo farò, lo dirò no
importa quello che realmente sta succedendo molto in
questo discorso perché è davvero necessario
concentrarsi su alcuni punti nel codice
e non prestare completa attenzione a cosa
sta succedendo e se solo inizi
leggendo attraverso di esso poi immediatamente cosa
salti è che c’è il tuo ciclo normale
variabile I e poi c’è questo
strano provvisorio e purtroppo lo è
non si adatta allo schermo ma dice
punto per
quindi ovviamente il tuo codice originale no
contiene qualsiasi variabile chiamata punto quattro tu
non può nemmeno creare una variabile chiamata punto
quattro in JavaScript, quindi questo è
immediatamente molto strano quindi vai e
oh sì ecco una versione più piccola così tu
vai e prendi semplicemente le fonti di v8
per queste cose punto quattro e lo trovi
da qualche parte in uno strano file di intestazione
chiamato SD valore di fabbrica e non c’è
questa cosa chiamata punto sottolinea quattro
e tu dici okay forse dovrei afferrare per
quello ora
e ti prendi per quello e trovi il
codice nel parse e in realtà non lo è
importa quale sia il codice è sufficiente
per sapere che è nel parser che tu
vai a leggere inizia a leggere il codice in giro
questo posto dove si dice punto per
il punto sottolinea quattro e tu
trova subito un commento utile così
le fonti v8 sono relativamente buone
ha commentato così puoi trovare questo commento
lì che dice okay abbiamo questo per
loop con la lettera contro vincolante e noi
riscrivilo come segue e cosa segue
è un’enorme regola di riscrittura per questo e così
nel commento e immediatamente puoi
vedi dove arriva il loop all’interno del loop
da lì c’è un ciclo dentro
il ciclo qui è questo ciclo e
allora c’è questo ciclo e non posso
ti dà davvero un’idea della v8
cervello degli implementatori perché hanno deciso di farlo
implementalo in questo modo ma immagino che
era perché volevano calzare il
ha portato i legami nella stessa vecchia stima
e come risultato hanno ottenuto qualcosa
implementazione inefficiente di quello per
i cicli for quindi spero che si risolveranno
e cose come core di JavaScript o
come Firefox per quanto ne sappia no
hanno questo lo SpiderMonkey che non fanno
avere questi problemi
quindi alla fine le persone V8 probabilmente lo risolvono
quindi ci sono due punti di vista qui
che gli interni sono importanti e tu
davvero bisogno di conoscerli ma c’è
anche un punto di vista che gli interni sono
completamente irrilevante e tu no
davvero bisogno di conoscerli e di entrambi
questi sono validi quindi non voglio provare
per convincerti che devi sapere
tutto ciò che accade all’interno di quelli
molti molti molti molti molti molti molti molti
molte molte linee di
codice di classe, ma è necessario avere il
comprensione ad un livello molto alto
perché quando in realtà lo importa
conta molto quindi per esempio ecco a
pezzo di codice da alcuni russi come
sito sociale di cui parlano le persone
programmazione
qualcuno ha provato a misurare qualcosa e
hanno scritto questo codice e tutti qui
in grado di leggere il codice JavaScript, quindi non lo sono
andando a passare attraverso quello e spiegare
quello che fa e lo gestiscono chiamano
questa bella funzione molte molte molte volte
e hanno scoperto che puoi farlo
il V8 propria nota come cinquemila volte
per millisecondo e questo suona bene
cool e poi provano a fare questo loro
ha detto okay, se lo prendessimo
array al di fuori della funzione di ricerca oh
in realtà al di fuori dell’indice e
al di fuori della funzione di ricerca e come
molto migliora le prestazioni e così
migliora le prestazioni ora puoi
chiamalo 14.000 volte al millisecondo
che tipo di senso ha che non lo fai
allocare array ogni volta che si chiama il
indicizzare o trovare e poi hanno scritto nel
questo post hanno scritto che oh questo significa
una riallocazione è costosa e io
è entrato nei commenti mi piace venire
nei commenti e nel dire alla gente
che hanno torto e ho detto di cosa si tratta
se faccio una funzione che fa una matrice
e invece di spostare la matrice
allocazione I tipo di spostare il
funzione che crea questo array e
Inizierò a chiamare questa funzione in questo modo
logicamente parlando dovrebbe nuovamente cadere
la performance fino in fondo
come quattro cinquemila operazioni per
millisecondo a destra
ma in realtà non lo è in realtà
quasi altrettanto veloce e questo è ciò che le persone
fare quando vedono questo sono molto
sorpreso e qui la scelta è quella di
profilo come si può usare su Linux per
esempio c’è uno strumento molto utile
chiamato perf che è a
pensa che possa essere collegato alla CPU
contatori delle prestazioni e aggregare il
le statistiche per te e v8 sono certe
livelli di integrazione con questo strumento così
con i nuovi kernel puoi farlo
anche ottenere le annotazioni come per
linea di assemblaggio essenzialmente per macchina
istruzioni di codice ma con un vecchio
kernel, almeno ottieni la funzione per
statistiche e cosa fa le prestazioni
i contatori mostrano qui che ce ne sono molti
i nomi delle funzioni in c ++ sono
molto a destra non si adattano al
Scorri ma puoi vedere che c’è un
molte cose legate alla creazione di nuovi
funziona qui è un sacco di codice C ++
responsabile di ciò perché dice nuovo
funzione si funzione si funzione nuova
chiusura così avanti e se tu
profilo la versione in cui è la matrice
assegnato in questa piccola funzione di supporto
scopri che non esiste una cosa del genere
succede lì ma c’è invece a
cosa chiamata rapida nuova chiusura fermata e
quello che succede qui è molto gentile
bizzarro è in v8
c’è questa cosa e scritto in
assemblea essenzialmente che può allocare
chiusure veloci ma non supportano o
non ha supportato l’allocazione di chiusure a
assegnazione rapida di chiusure se il
chiusura conteneva un array letterale
al suo interno, quindi, cosa è successo effettivamente?
vai al codice di nuovo al codice quando tu
aveva un array all’interno dell’indice
funzione l’ allocazione di un indice
funzione stessa che si verifica ogni volta
che tu chiami funzione fine era molto
costoso doveva andare al runtime
e fare tutto il materiale in fase di esecuzione e
non appena ho spostato l’allocazione dell’array
fuori allora l’assegnazione dell’indice
le funzioni sono state velocizzate notevolmente e
anche se che sei allocare capo un
funzione e l’array ogni volta
che tu lo chiami l’allocazione stessa
non è così costoso perché succede
nel nuovo spazio è solo un bernoccolo del
puntatore è molto molto veloce ok quindi se tu
eseguire questo codice sulla nuova v8 e persone
le persone v8 in realtà hanno insegnato questo
pezzo di assemblaggio manoscritto come
alloca chiusure con letterali all’interno
così ora entrambi i casi sono ugualmente veloci ok
ecco un altro esempio molto interessante
dallo stack overflow
qualcuno ha scritto cha-cha 20 cifrario in
JavaScript e non importa cosa
il tuo 20s è solo un po ‘di numeri crunching
roba II sì che è essenzialmente è
è la parte principale dell’avviso di chat
e c’è un metodo di supporto chiamato
citazione qui intorno che è chiamata molto
di volte nel ciclo e la persona che
ha chiesto la domanda di overflow dello stack che era
in realtà curioso cosa succede se lui
prende l’attuazione di questa citazione
intorno e in linea in questo
funzione che chiama così ha misurato
la versione senza inlining e it
era come 20 megabyte al secondo , non è così
sapere se è veloce se è lento
per una cifra non importa per il
scopi di questo discorso poi prende questo
implementazione di questa funzione cosa
intorno e basta inserire il codice in
questo ciclo manualmente completamente inlining
l’ entrare in questo loop in un enorme casino
dell’aritmetica e la gestisce e di
Naturalmente l’aspettativa è che funziona
più veloce è in realtà eseguito dieci volte
più lentamente così fa la faccia così
indovina e non è molto felice e lui
Dice che ho sentito da qualche parte che inlining
deve migliorare le prestazioni perché no
capita e ho guardato questo esempio e
Ho detto bene che hai questa funzione lì
che fa certe cose ai numeri
e cosa succede se si applica il fantastico GS a
e questo fantastico GS è interessante
modo standard in cui metti l’utente come
meditazione nel tuo codice e poi
all’improvviso tutto sembra molto molto veloce
veloce così come ho detto usa l’annotazione
l’ Osman il tuo codice come quello e la VM
lo accelera e li vedo
ha fatto accelerare tutto fino al
fondamentalmente la stessa prestazione che era
lì prima e ovviamente è necessario
metti un commento aggiuntivo lì quale
lo dice alle persone che non lo fanno
capire tutto sulle prestazioni o
macchine virtuali altrimenti lo faranno
rimuovi questo così ed è per questo che io
davvero bisogno di sapere le cose di solito quando
diciamo performance che intendevamo
usato per dire che vai in GS perv
dot-com e scrivi qualche micro
punto di riferimento e tu sai tutto lì
è conoscere il JavaScript
performance ma tu sei un tipo Jesper
dieta è ora in questo stato perpetuo di
riscrivere e non è più possibile utilizzare in modo
lavori per quelli di voi che non lo fanno
lo so come quante persone hanno mai usato
Jesper dalle loro vite qui non è così
molti oh questo è buono che è buono in realtà
non sei viziato non sei la tua mente
non sono corrotti da questa cosa così
era questo sito dove potresti scrivere un po ‘
codice e quindi si preme il pulsante di esecuzione
prova e ottieni come operazioni per
millisecondo per quei test che tu
ha scritto e altre persone potrebbero anche correre
quei test e poi i dati erano
aggregato e potresti vedere dentro
alcuni browser diversi OSS diversi
numero medio di prestazioni ma il
il problema è che le persone scrivono molto
benchmark strani e non lo fanno
capire come usare correttamente quindi se
basi le tue decisioni su ciò che ottieni
decisioni davvero strane per esempio
qualcuno ha provato a scrivere questo test che
cerca di misurare qual è il modo più veloce
contare le lettere e nel testo e loro
scoperto alcuni modi molto veloci
firefox puoi vedere così questo è
operazioni al millisecondo o al secondo
quindi più alto è il migliore e firefox così
c’è questa linea viola che piace è
enorme come se fosse più veloce di qualsiasi altra cosa
hai visto prima nella tua vita
è come tesla di javascript e lo è
questa cosa spaccata lassù così il più veloce
a quanto pare in Firefox a contare
lettere e nel testo è dividerlo per
lettera e quindi prendi la lunghezza del
array e sottrarre 1 restituisce il
il giusto risultato è un po ‘ma è un po’
mmm cosa è successo veramente qui e
l’altro che è anche veloce dentro dentro
tutti i browser non veloci come il
il primo ovviamente ma ancora molto veloce
è per scorrere su questa stringa ma per
iterazione non si usa il normale come
per I da zero a lunghezza della stringa
si inizia a tagliare la stringa con a
fetta e questo è ancora una volta strano
perché quello che mi aspetterei sarebbe una fetta
lento
quindi sono risultati davvero strani e se
lo prendi come per il tuo valore nominale
prenderà strane decisioni sulla base di
che e non si deve farlo in modo da
dovrebbe invece dubitare di tutto come
letteralmente tutto ciò che dovresti dubitare se
si sta se si sta andando a casa ci dovrebbe
Dubito che tu abbia preso l’autobus giusto e
ovviamente dovresti dubitare del micro
parametri di riferimento quindi i micro benchmark
questo come pensi di provare a usare quando
vuoi misurare qual è il costo di a
operazione singola e come si fa?
beh, certo, scrivi il codice come
questo tu prendi la data attuale di te
esegui l’operazione quindi sottrai
la data corrente sottrai il
precedente data corrente dalla corrente
data corrente giusta e ottieni una specie di
la lunghezza va bene abbastanza semplice ma cosa
se l’operazione è più veloce del
l’orologio di solito si aspetterebbe che il
assegnazione ad una variabile per esempio
non richiede nemmeno un millisecondo
beh forse ha usato per prendere un millisecondo
indietro negli anni ’90 ma non ora così facile
la risposta è solo per ripetere l’operazione
più volte e poi dividere il tempo
dalla quantità di iterazioni che tu
ha preso o diviso la quantità di iterazione
Con il tempo dipende da ciò che si vuole
ottenere come risultato quindi questo è il
aritmetica dalla scuola ma forse no
tutti sono andati a scuola, quindi lo farò
ripeti un po ‘per cui vuoi trovarlo
il costo dell’operazione ha segnato C così
tu se lo ripeti 10 volte e poi
lo scrivi per n poi e se ne va e
il tipo di ottenere il giusto costo
aritmetica 101 quindi se si guarda
l’esempio con l’affettatura di una stringa
uno per uno, quindi cosa succede con questo
esempio che cosa lo rende così veloce è quello
la GS per per il benchmark GS che è
questa libreria sotto la GS perv essa
genera il wrapping del codice JavaScript
questo nel ciclo e forse se spendiamo
un’ora a fissare questo
Codice JavaScript scopriremo cosa
la schiena è la schiena è che arrivi
con una stringa vuota sul secondo
iterazione del ciclo esterno giusto per te
tagliare la fetta di stringa fetta fetta di esso
termina quando la stringa è vuota e quindi
la stringa non viene mai inizializzata semplicemente
ripetere con il
con stringa vuota tutte le operazioni così
la ripetizione inizia con una stringa uguale
alla stringa vuota e volevamo ottenere
massa come quella, ma in realtà abbiamo ottenuto il
massa così, così abbiamo ripetuto un
operazione una volta e poi lo ripetiamo
niente n meno 1 volte e poi noi
diviso per n e tu hai il costo di
operazione divisa per N e il costo di
l’operazione è un numero molto piccolo e
la quantità di ripetizioni è molto alta quindi
è approssimativamente non costa nulla
giusto così molto semplice questo è molto
esempio comune di riferimento Jaso jesper
abuso quando le persone non prendono in
conto che l’operazione dovrebbe prendere il
la stessa quantità di tempo ogni volta che corri
e, ma in realtà non è molto facile
per raggiungere ciò nel mondo moderno così
per esempio qui un altro caso dal
GS nascita dove qualcuno ha provato a misurare
qual è il modo più veloce per convertire un
stringa a un numero e si scopre
ancora una volta sul firefox il modo più veloce per
trasformare la stringa in un numero è una doppia
tilde quindi se conosci la complessità di
la semantica di JavaScript la tilde è a
negazione bit a bit destra e doppia
la negazione bit a bit non è una negazione in
Va bene , è solo identità così quando tu
dichiarare ok double tilde per la vittoria
convertiamo tutte le analisi int in
raddoppiare fino a loro sono considerevolmente
più veloce ovviamente la risposta è no
compilatori javascript just-in-time
compilatori sono abbastanza intelligenti
i cani non sono le persone più intelligenti ma a
Almeno loro possono passare al tuo codice e
allora puoi osservare come è il programma
correndo e possono ottimizzare mentre
sta correndo così la tua matematica dal primo
il voto non si applica più realmente
almeno una versione ottimizzata e
versione non ottimizzata non ottimizzata
versioni ottimizzate insieme e poi tu
ripetere a più volte il non ottimizzato
versione allora viene JIT e lo ottimizza
quindi diventa un po ‘complicato ma
in realtà è ancora più complicato
perché possono esserci più ottimizzazioni
versioni come Safari per esempio ha
diversi trucchi e lacrime ottimizzanti
su
mentre il codice viene eseguito e diventa più caldo e
più caldo e se prendi in considerazione tutti i tipi di
costi come GC e costi di compilazione e
la matematica diventa davvero caotica e tu
non è più possibile usare una semplice matematica di cui hai bisogno
andare all’università e prenderne un po ‘
analisi quindi è necessario superare in astuzia il
compilatore just-in-time da misurare
qualsiasi cosa veramente e se si programma
lingue come Java, ad esempio, tu
hai già strumenti per farlo
ad esempio il Java ha il micro Java
cablaggio di riferimento gmh e aveva a
un sacco di ingegneria a cui dedicarsi
superare in astuzia l’ hotspot ma in JavaScript
non hai davvero questi strumenti e
punto di riferimento J di non fare molto per
superare in astuzia il JIT che ti mostrerò
esempi di ottimizzazioni ora su
diapositive ma dovresti davvero capire
che sto per mostrarvi loro sulla
livello sorgente ma non è come loro
succede nella realtà
così sono accaduti nel più complicato
rappresentazioni intermedie ma per il
scopi del discorso sto ignorando tutto
la teoria del compilatore e sto solo facendo
cosa voglio fare, quindi cosa succede con
questo punto di riferimento con la doppia tilde è quello
il cane il cane JIT che è intelligente
abbastanza vede che non cambierò mai
il ciclo è una costante davvero l’ occhio
viene assegnata una stringa costante e tu
mettilo lì e poi dice oh
ma so come applicare il bitwise
negazione alla stringa piena di numeri
e lo fa e lo fa ancora e
finisci con il solo incarico del
costante a una variabile che non è quella
costoso è essenzialmente zero e questo
sono le ottimizzazioni chiamate costanti
propagazione e la maggior parte dei trucchi tutti
dei trucchi di questi tempi e lo fanno
quindi puoi dire ok, posso ingannare il
compilatore Posso ingannare la costante
propagazione e se io faccio l’io
non costante genera solo una stringa
in base all’ora corrente, ad esempio
e naturalmente la squadra investigativa sarà tutto
prendere dal panico e scappare ma non è questo
la risposta sbagliata McFly questo non sta andando
ingannare il compilatore
così il compilatore lo osserverà mentre
non è una costante che effettivamente è un
loop invariante quindi non c’è motivo di farlo
eseguire questa operazione ancora e ancora
nel ciclo puoi semplicemente spostarlo e
eseguilo al di fuori del loop e tu
di nuovo misurando nulla di ciò che sei
misurare un incarico di alcuni pre
valore calcolato a una variabile, naturalmente
il calcolo è ora accadendo nel
codice ma è successo in un po ‘fuori
di come quello che stai misurando questo è
chiamato di nuovo ciclo di codice invariante del ciclo
la maggior parte dei bambini lo fa
possono andare più avanti e poi
possono osservare che nessuno è realmente
usando la variabile J e se nessuno sta usando
La variabile J quindi J zero non viene utilizzata
o se nessuno sta usando Chi zero
allora forse non ho più bisogno
o e non ci sono effetti collaterali da
calcolo della stringa due della data ora
quindi è tutto completamente morto quindi la tua fine
con un loop vuoto e ovviamente poi
puoi anche chiedere se sei come se
sei molto intelligente tipo di merda di cane voi
posso chiedere perché allora c’è un ciclo giusto
e poi anche il ciclo va via e
questo è chiamato eliminazione del codice morto e
la scommessa è, nel senso che non è così
fare qualsiasi cosa osservabile, qualcosa di utile
qualsiasi cosa usata dal codice successivo e
l’esempio di prima con una divisione di
una stringa di Firefox è in realtà intelligente
abbastanza per capire che la divisione è
stringa costante dalla variabile dal
somma chiama altra stringa costante e
prendendo le lunghezze del risultante
array in realtà non fa nulla
osservabile dall’esterno così questo è
tutto completamente rimosso ed eliminato se
assegni questo valore ai due
da qualche parte poi è diverso
situazione quindi cosa dovresti avere
capito da questa piccola introduzione
che ottimizzatori mangiano micro
punti di riferimento per la colazione e per il pranzo
e cena e di notte anche loro
svegliati e mangiali e alcune persone
voglio davvero creare un micro a prova
benchmark che l’ottimizzatore ha fatto trapelare il mio
la raccomandazione è di solito no
per niente piace solo trovare qualcosa
più utile per correggere alcuni bug nel tuo
codice, ma se si vuole veramente ad almeno
prova allora dovresti seguire un po ‘
semplici requisiti che dovresti provare a
evitare questa ottimizzazione molto comune quindi
attendere costanti e invarianti di loop in
il codice morto e per l’amore di Dio
verificare i risultati del benchmark
stai facendo perché molte persone solo
scrivi qualche benchmark ma in realtà no
facendo ciò che si aspettano di fare
perché non controllano i risultati e
controllando i risultati si combatte anche i morti
codice di roba perché ora stai usando il tuo
valori calcolati in modo che possiamo provare a risolvere
questo benchmark facendo applicando
queste regole creiamo due non costanti
valori e iniziamo a scambiarli nel
loop per confondere il compilatore in modo che il
variabile applichiamo il doppio fino al
due non è più un ciclo invariante e quindi
quindi controlliamo che tutto sia abbastanza gentile
buono da usare il risultato del doppio
operazione tilden e questo non è male
di solito dovrebbe essere abbastanza per davvero
misura qualcosa ma se hai un
compilatore davvero intelligente e la nostra speranza è
che in futuro tutti i compilatori
sarà molto intelligente
quindi potenzialmente non è ancora abbastanza
perché sono ciò che i compilatori possono fare
che possono prendere questo ciclo e dire hey
che dire se lo faccio due volte meno
iterazioni ma ripeto il corpo dentro
due volte così fanno alcuni compilatori compilatori C ++
che tutto il tempo per piccoli anelli e
quello che succede ora è che scambi e
poi cambi di nuovo ed è come se tu
mai scambiato nulla quindi i valori
di nuovo diventa loop invariante per questo
loop e perché loop ti invariano
finire con qualche codice morto e alcuni
codice invariante e ancora non misura
qualsiasi cosa si chiama questa ottimizzazione
loop srotolamento v8 non lo fa
la luce è in realtà come dal 2012 che ho
ho dato questa variante parlante
varianza dal 2012 e non fa ancora
fallo ma voglio indurre i paranoici a
2012 in due persone il timore di Dio il
modo in cui dovresti avvicinarti ai codici come
hai visto che le macchine virtuali sono relativamente buone
ottimizzare le cose
quindi dovresti avvicinarti al tuo javascript
codice con la presunzione di prestazioni
quindi la presunzione di prestazione è
che se si scrive il codice è ragionevole
dovrebbe essere ragionevole veloce e se lo è
non ragionevolmente veloce allora la VM è a
colpa non te, ma le persone hanno anche il
cosa chiamata bias di conferma che è
pensano che qualcosa è lento e
scrivono alcuni punti di riferimento e il
servizio di riferimento e il loro codice è
ragionevole ma ma la loro esecuzione di
questo codice è cattivo e dicono che io sono d’accordo
sapere questa caratteristica della lingua è
lento quindi non andrò e non lo farò
dire a qualcuno che questo è lento lo farò
scrivi un post sul blog che ti avviserà
tutti gli altri dall’usare questa lingua
caratteristica per esempio c’è questo
presunzione che le catene prototipo siano
lento e le persone scrivono parametri come
che loro dicono che io creo profondamente
prototipo annidato catena quante persone
so cosa object.create sono I’m just
controllando che nessuno stia dormendo lì
quante quante persone sanno cosa
obiettare ciò che molti di voi scrivono
JavaScript in realtà va bene, non quello
molti vedo che vedo
così object.create crea l’oggetto con
un dato prototipo e poi se nidifichi
che ottieni un prototipo profondamente annidato
catena c’è un minimo tributone su questo
Scorri pure così tante persone lo sanno
almeno almeno si okay okay
evviva per locazione così e poi loro scrivono
questo ciclo triplo annidato per qualsiasi cosa
la ragione è triplamente annidata, non lo so
e quindi accedono a questa proprietà
il prototipo di un prototipo di a
prototipo di un prototipo e loro
misurare quanto ci vuole al di fuori di
questa funzione chiama e poi scrive
un’altra funzione che incassa il valore
di questa proprietà al di fuori di questo ciclo
e tu usi semplicemente la variabile dentro e
quindi il driver di riferimento all’avanguardia
è anche nel gioco che chiama questo
funzione le misure quanto tempo ci vuole
e si misura e si scopre che
in effetti se si guarda su la proprietà
il prototipo molte molte volte è
otto volte più lento del semplice guardarlo
su una volta e mettendo in cache il risultato e voi
scrivi un post sul blog questo è letteralmente
tratto da un post sul blog che dice di no
usa il prototipo
sono lenti con un grande timbro su di esso
poi naturalmente vengo e dico ok come
a proposito di rendere più difficile cosa invece se
di mettere una proprietà normale sul
prototipo profondamente annidato ho messo il getter
sul prototipo e ovviamente su tutti
ho sentito che i getter sono più lenti di
proprietà normali e poi c’è a
prototipi nella cosa quindi dovrebbe essere
molti milioni miliardi di volte più lenti
a destra risulta che in realtà è più veloce
renderlo un getter e le persone sono davvero
sbalordito da questo e ti dicono
sono un mago oscuro o qualche tipo ma tu
può guardare nel codice generato in questo modo
è lo screenshot del mio strumento chiamato nostro
Hydra che ti mostra quale codice è gentile
di generato questo è un intermedio
rappresentazione utilizzata dal compilatore e
lo puoi vedere se lo fai diventare getter
poi improvvisamente è in linea nel loop
dice entra in linea lasciando la linea e
non c’è niente tra quelli così il
perché stava solo restituendo una costante
giusto e poi quella costante è giusta
aggiunto a questa cosa contatore ancora e
di nuovo così in qualche modo, una volta che abbiamo fatto un
mi sono messo in fila e lo stesso
non stava accadendo con il normale
proprietà stava facendo questo era
chiamare questa cosa molto spaventosa chiamata
carico di nome generico e guardando in su
ogni volta ancora e ancora nel ciclo
quindi risulta che il post del blog era
basato sul molto molto molto vecchio v8 che
impossibile gestire le proprietà definite
sui prototipi come potevano
gentile potrebbe gestire i getter definiti
sui prototipi così raccoglie potrebbe
in linea e tutto era molto buono ma
la proprietà che avrebbe guardato attraverso
questo processo molto lento ancora e ancora
se provi la nuova v8 poi tutto
è in realtà un tipo di bene e il
le prestazioni sono le stesse perché il
V8 più recente può gestire bene e quando io
dì che eri del 2013 forse
qualcuno stava usando nota ole punto 4 punto
qualcosa che ha usato la nazione per mangiare
ok tutto va bene a tutti
rallegrandosi e la cosa che tu
dovrebbe osservare qui è che il
codice prototipo di attraversamento della catena che va
il prototipo e trova dove
proprietà buon codice invariante ciclo
mosso da qualche parte fuori dal giro e
non stai misurando nulla di nuovo io
essenzialmente così va bene facciamo qualcosa
completamente diverso
beh in realtà lo stesso, quindi cosa succede se corro
lo stesso benchmark due volte come ho misurato
la stessa funzione due volte per la prima
benchmark e per il secondo benchmark
così come l’ aspettativa è che niente
cambia forse diventa un po ‘
più veloce perché non c’è alcun costo
ottimizzazione più
si scopre no in realtà è diventato più lento
per qualche strana ragione e lo ero
mostrandoti prima che i compilatori lo siano
intelligente e tutto è buono e puoi farlo
balla e sii felice e scrivi qualunque cosa
codice che vuoi ma in realtà il compilatore è
anche molto complesso quindi hanno bug di
tutti i tipi dentro e questo è quello che sono
cercando di mostrarti che sono pieni di
bug e dovresti essere pronto ad affrontare
quegli insetti così che cosa è successo così possiamo
di nuovo uso l’errore Hydra e possiamo vedere
che ci sono molte versioni dello stesso
funzione prodotta dall’ottimizzazione
compilatore e il colore rosso significa che il
ottimizzato e ho bisogno di te ottimizzato di nuovo
e poi c’è un colore viola che
significa anche ottimizzare ma un diverso
una sorta di ottimizzazione e poi
prodotto una versione che è stata usata
dopo di ciò e non è stato ottimizzato
di nuovo quindi è una delle ottimizzazioni
raggiunto un punto stabile ma quando guardiamo
a che tipo di punto stabile ha raggiunto
troviamo che è una stalla molto strana
punta così la variabile contatore che
accumula l’alcuni dei nostri opzionali
accesso agli oggetti di scena ora è in scatola, quindi carichi
dalla cosa che aggiungi e poi
casella il contatore ancora e ancora e
il pugilato così v8 usa questo
rappresentazione di numeri di doppi
è inscatolato in modo da conservarli in un
oggetto heap allocato sull’heap e
lo immagazzini lì e ne assegni uno
nuovo ogni iterazione del ciclo, ovviamente
che è costoso si produce un sacco di
spazzatura ed è per questo che si è stabilizzata
una versione molto più bassa in modo da poter scavare
attraverso il localizzatore di bug di perline e trova
il retro
e quello che stava accadendo è che la la
non v’è che non c’era alla fine del
il punto di riferimento è la linea che era
stampando il contatore e si scopre
questa linea stava causando tutti i tipi di
gli shenanigans si verificano nella v-8
interni e c’è stata una soluzione per
devi solo nascondere il fatto
stai aiutando questa variabile a
qualcosa per esempio che potresti avere
forzato convertito in stringa con a
chiamata di metodo e quindi questa inferenza
cerca di capire come rappresentare
variabili nel codice come quelle a
mettere i registri della macchina come un
per esempio, unboxed raddoppia
più a lungo essere confuso e poi tutto
correrebbe di nuovo solo veloce questo indietro
è stato risolto in modo da non mettere due corde
ovunque così gran parte della scatola che sono
mostrandoti che sono aggiustati, così non lo fai
deve usare qualsiasi lavoro qui è per
qualcosa di non fissato in modo che io possa impilare
trabocco domanda qualcuno cerca di
misurare ciò che è come quanto costa
usare getter e setter sull’oggetto
e scrivono questo punto di riferimento e lo farò
accelerare un po ‘per rendere il
tempo e sulla nuova v8 sono le tre
qualunque cosa io sappia è milioni di io
non riesco a leggere i numeri milioni giusto sì
tre milioni di operazioni al secondo e
su un vecchio v8 è considerevolmente più veloce
come se avesse diritto a ottocento milioni
e naturalmente tu sei di nuovo molto
sorpreso cosa sta succedendo qui perché
pendo v8 persone lavorano lavoro e fanno
tutto più lento, forse è ora
ritirarsi quindi se prendi questo e scrivi
è come rimuovere il punto di riferimento di J da
l’immagine e tu scrivi questo
funzione che è ciò che il punto di riferimento
definisce alcuni setter getter e prova
in un loop ancora e ancora e corri
una volta questa funzione e tu la esegui
due volte e rallenta di un fattore di
100 su v8 quindi sì di nuovo nostro aiuto
guida che è molto sorpresa lì lì
è una cosa chiamata il digiuno
rappresentazione di oggetti in v8 e
c’è un
per verificare se il tuo oggetto ha un veloce
la rappresentazione è usare questi interni
funzioni necessarie per costruire v8 ed eseguire
attraverso la bandiera speciale ma puoi
controllalo e se lo esegui con a
FAQ speciali e usa quella percentuale più velocemente
prova corretta si scopre che quando
tu chiami questa funzione la seconda volta
l’ oggetto che viene creato non lo è
avere una rappresentazione veloce o di proprietà
ed è per questo che rallenta così tanto
c’è una cosa complicata che sta succedendo
qui non voglio entrare nella teoria
dettagli, ma come si può lavorare intorno ad esso
è chiamare oggetto o creare su questo
oggetto
quindi c’è un meccanismo interno che
dice se si mette un oggetto come prototipo
ad un altro oggetto qui quando non lo siamo
anche usando c’è il punto dell’oggetto
crea allora la forza v8 lo converte in
la rappresentazione veloce di nuovo così puoi
chiamarlo una volta chiamarlo due volte non rallenta
giù più chiama tre quattro volte fa
l’installazione poi rallenta così perché lì
è un limite polimorfo raggiunto e
limite dei polimorfismi raggiunto nel
codice generato va bene si può dire ok io
andrà ai metodi della vecchia scuola di
creando getter e setter, lo farò
scrivilo manualmente come i nostri antenati
fatto nel 1900 quindi risulta che va bene
ma è ancora veloce come il la
caso più veloce possibile, ma almeno
non ha queste strane gocce
è abbastanza prevedibile, quindi puoi farlo
passare a un approccio orientato agli oggetti se
sei mai stato un programmatore Java di te
può dire orientamento oggetto posto è il
rispondi a tutto se è una classe
non basta fare due classi nel
fabbrica e qui creo una scatola che
Scatena il nostro valore e poi ho getter
e setter su questo e poi creo
questa scatola oh che c’è un sì che è
com’è, è quasi equivalente
al nostro codice precedente e questo è in realtà
il modo più veloce per farlo in v8 v8 è
davvero ottimizzato per questo stile di
programmazione orientata agli oggetti in cui tu
avere delle lezioni e ne hai alcune
metodi sui prototipi e cose simili
così non so che sei felice che io sia
tipo di felice ma so dipende dal tuo
stile di programmazione forse hai insegnato
quella
ecco perché è importante saperlo
fondamentali e puoi guardare in altro
VM, quindi questo discorso sta per essere
8 per lo più e in procinto di essere 8 dollari ma questo
non importa che non puoi fare il
lo stesso per le altre macchine virtuali quindi javascript
core è possibile creare javascriptcore sul
Mac facilmente controlla qualche fonte
e costruisci e ha anche questo
drop-off quando chiami la prima versione
di funzione è molto veloce molto veloce
poi un po ‘più lento e questo è
perché puoi ancora puoi chiederlo a
stampa l’intermedio
rappresentazioni utilizzate dal compilatore
in tutti i tipi di cose
e guardalo e come se sapessi come
leggere lo smontaggio e le cose del v8
così è facile leggere il
Roba di base di JavaScript e così là
sono un sacco di codice che non voglio che tu faccia
leggendo tutto rimuoverò tutte le cose
che non importa ma puoi vedere
che nella prima versione è solo
controllare alcune condizioni preliminari e poi è
nelle righe il set ha chiamato e linee Inter
anche la chiamata get e dice conosciuto
kohli quindi tutto è buono ma dopo
la terza chiamata nella terza chiamata che
dice ok non farò più alcun inlining
Inizierò a chiamare attraverso il
metodo di chiamata generico e quindi ecco perché
rallenta perché ce ne sono alcuni
contatori come il limite del polimorfismo raggiunto
è per questo che è più lento ok nel breve periodo
avremo un po ‘di tempo, lo farò io
Sarò veloce così qualcuno ci ha provato
misurare se la chiamata di funzione è il
più veloce della chiamata al metodo o dell’altro
modo in cui hanno creato una funzione
questo fa un po ‘di hashing di alcune stringhe
non importa quello che fa e poi
mettono questa funzione sul prototipo
di alcuni oggetti nello stile Java Java
di nuovo così hai un oggetto con a
metodo che un oggetto non contiene
qualsiasi cosa solo questo metodo e poi tu
confronta tu esegui questa funzione su alcuni
stringhe e quindi si esegue questo metodo
che è la stessa funzione su alcuni
archi e si scopre che il
la funzione è notevolmente più lenta e il
il metodo è più veloce quindi orientato agli oggetti
la programmazione vince ancora Oh al
programmazione orientata agli oggetti in modo che possiamo
fai questa domanda e per favore non mostrare
Qualunque cosa ho intenzione di mostrarti ora
la sua è
noi andiamo ai partecipanti quindi se prendi questo
funzione di configurazione del prototipo di riferimento che
stava preparando il nostro benchmark e tu
aggiungi semplicemente queste corde lì dentro come
questo video JavaScript con questo
trucco strano e poi lo si esegue di nuovo
quindi è la stessa performance tra
funzione nel metodo così ovviamente
qualcosa non è davvero proprio qui di nuovo
il nostro utile di fase così se guardiamo nel
IR hider cosa stava succedendo è quello
benchmark di funzione in realtà non è mai stato
ottimizzato per tutto, quindi era in esecuzione
la versione non ottimizzata che è
considerevolmente rallentato e ottimizzato
versione ed è per questo che è stato più lento e
c’è una spiegazione ma io tutti
riassunto per te come yada-yada
bla-bla
quindi la cosa è quella funzione
chiamata e la chiamata al metodo è stata fatta
diversamente nel v8 e nel
l’ottimizzazione non lo stava semplicemente innescando
non stava contando la cosa giusta per
contare e aggiungere l’aggiunta di cose
che ho aggiunto solo perché lo fosse
ottimizzato perché ha iniziato a contare
le cose giuste questo è un po ‘risolto
quindi non dovrebbe essere più un problema di nuovo
e ma la cosa è che siamo di nuovo
misurare il ciclo vuoto perché se noi
guardare in Hydra ire ciò che sta accadendo
l’intero codice hashing è stato spostato
perché le stringhe che stavamo tagliando
erano costanti quindi tutto l’ XS è quello
indici costanti come le lunghezze sono a
costante di se è una stringa costante
e cose del genere tutto è stato spostato
alcuni di questi sono stati calcolati e piegati
così può essere il contrario così
questo è l’ultimo tipo di diapositive perché
Sono a corto di tempo, quindi lavoro
buio ora e io lavoro sul dardo VM ma
le persone che fanno il compilatore da dardo
a JavaScript vengono da me e chiedono
domande a volte perché ero abituato
lavoro su v8 e loro stavano compilando
il ciclo straniero in JavaScript e
stavano producendo questo codice e lì
è questo utile controllo lì che è
controllando che non stai modificando il
array perché questo è il lavoro
questa semantica del dardo e tu vuoi
lanciare un’eccezione quando si modifica a destra
qui nell’iterazione e detti
c’è un assegno e di
costa qualcosa così se commentiamo
è il 18% più veloce e puoi aiutarci e
renderlo in qualche modo più veloce del 18% senza
commentandolo e ho detto bene no
problema
prendi il tuo codice e poi lo scrivi
come quella
quindi sostituisci la chiamata al metodo con
qualcosa di strano qui, quindi se lo sai
basta tenere semantica e coma
l’operatore restituisce l’ultimo valutato
espressione che è questa funzione a
chiama e poi lo chiami e questo codice
non viene mai eseguito perché questo è giusto
un’eccezione che non esce mai
arriva a volare fuori da questo codice perché tu
mai modificato l’array e in qualche modo esso
rende più veloce come ho misurato e
rende davvero più veloce e solo per
riassumere così in qualche modo acceleriamo il
codice del 18% sostituendo la chiamata al metodo
con alcune cose strane che sembrano
una persona che è uno ero come qualcosa
altro strano è successo ad esso e in
il codice che non esegue mai e abbiamo accelerato
tutto su così che cosa sta succedendo lì
è che non sappiamo cosa sia questo
il codice non è mai stato eseguito e noi davvero
si basa sulle informazioni raccolte da
il codice eseguito per ottimizzarlo e
perché non è mai stato eseguito, no
sapere cosa sta succedendo lì e il
metodo non eseguito chiamate di metodo e non
sono stati trattati gli accessi alle proprietà eseguite
in modo diverso nella v8, quindi ho sostituito il
chiamata metodo non eseguita e all’interno di non
eseguito le tasse di proprietà e basta
aiutato a ottimizzarlo lo ha aiutato a
capire che non è mai stato eseguito
e l’ha aiutato a capire che il
le lunghezze non cambiano mai perché come v8
può vedere che c’è solo l’ accesso alla matrice
e nessuna funzione chiama e in the
codice quindi può solo supporre che questo sia
tutto quel codice e farlo e sì
quindi questa è una spiegazione non importa così
Consiglio vivamente di dare un’occhiata
i tuoi algoritmi prima e poi iniziano
micro benchmarking e aspetta un secondo così
c’è stato un primo esempio con questo e
una strana direttiva di uso fantastico di nuovo noi
può guardarlo nel nostro scarico alto
scoprire che il
v8 ottimizzava continuamente il
funzione in cui abbiamo delineato tutte le cose
dentro e c’era il mercato in rialzo in a
posto strano che dice cose strane e
se vedi il codice così se vedi
la situazione come quella in cui il tuo
funziona continuamente essendo il
ottimizzato e ottimizzazioni mai
stabilizzare quindi dovresti solo andare e
file una v8 torna davvero perché è un v8
non torni indietro e c’è un guadagno
la spiegazione non importa c’è a
più sano di mente e mettiti in questo
enorme commento quindi il motivo per cui l’enorme
il commento ha funzionato è quello perché abbiamo mangiato dentro
si basa sulla dimensione del codice sorgente per
prendere decisioni inlining a causa di alcuni
manufatti storici che sarebbero
alla fine ho il sospetto che ci sia un
al posto di lavorare molto bene
disabilitare la funzione di inline è semplicemente aggiungerne alcuni
troncamento a questo carico dalla matrice
quindi per favore non assumere mai quella lingua
la funzionalità deve essere lenta , andare e chiedere
dai tuoi simili senatori più vicini o
qualunque cosa e le persone in parlamento a
fare mascelle buone caratteristiche veloce proprio il
bug nel bug tracker v8 e persone VM
sono davvero tuoi amici, sono tuo amico
anche se non sono più una persona v8
quindi ricorda di valutare questa sessione
qualunque ti ringrazio molto per il tuo
Attenzione
tu

Please follow and like us: