Aprendi com os livros que você deve escrever para um loop como este:
for(var i=0, len=arr.length; i < len; i++){
// blah blah
}
portanto, o valor arr.length
não será calculado a cada vez.
Outros dizem que o compilador fará alguma otimização para isso, então você pode simplesmente escrever:
for(var i=0; i < arr.length; i++){
// blah blah
}
Eu só quero saber qual é a melhor maneira na prática?
javascript
performance
loops
wong2
fonte
fonte
for ... of
loop nesta competição? A sintaxe parece ainda mais fácil que o loop for sem cache, e quero saber se devo mudar para o uso de loops for.Respostas:
Depois de realizar este teste com os navegadores mais modernos ...
http://jsben.ch/dyM52
Atualmente , a forma mais rápida de loop (e na minha opinião a mais sintaticamente óbvia).
um padrão para loop com cache de comprimento
Eu diria que esse é definitivamente um caso em que aplaudo os desenvolvedores de mecanismos JavaScript. Um tempo de execução deve ser otimizado para maior clareza , não inteligência .
fonte
++i
.for(var i=0, len=myArray.length; i<len; ++i)
Verifique jsperf.com/caching-array-length/84var
instrução. Como está escrito,len
é realmente definido como você sugere.A maneira mais rápida e absoluta de percorrer uma matriz javascript é:
Consulte http://blogs.oracle.com/greimer/entry/best_way_to_code_a para obter uma comparação completa
fonte
var
(o outrolen
se torna uma variável global). Além disso, consulte jsperf.com/loops para obter mais referências de loop.Em junho de 2016 , fazendo alguns testes no Chrome mais recente (71% do mercado de navegadores em maio de 2016 e aumentando):
Acredito que esse segmento é muito antigo e é programador enganoso pensar que precisa armazenar em cache o comprimento ou usar movimentos inversos com decréscimos para obter melhor desempenho, escrevendo código menos legível e mais propenso a erros do que um loop simples e direto. Portanto, eu recomendo:
Se o seu aplicativo iterar muitos itens ou o código do seu loop estiver dentro de uma função usada com frequência, um loop for direto é a resposta:
Se seu aplicativo realmente não percorre muitos itens ou você só precisa fazer pequenas iterações aqui e ali, o uso do retorno de chamada padrão forEach ou qualquer função semelhante da sua biblioteca JS de escolha pode ser mais compreensível e menos propenso a erros, pois O escopo da variável de índice está fechado e você não precisa usar colchetes, acessando o valor da matriz diretamente:
Se você realmente precisar riscar alguns milissegundos enquanto itera sobre bilhões de linhas e o comprimento da sua matriz não muda durante o processo, considere armazenar em cache o comprimento no loop for. Embora eu ache que isso não seja realmente necessário hoje em dia:
fonte
for(let i=0, j=array.length; i < j; i++)
, o forward for loops acelera consideravelmente. Em alguns testes que fiz, ele venceu, na maioria, estava dentro da margem de erro ou no loop reverso.Se o pedido não for importante, prefiro este estilo:
Ele armazena em cache o comprimento e é muito mais curto para escrever. Mas ele irá percorrer a matriz na ordem inversa.
fonte
i--
retorna um número e, uma vez que o número é0
a condição, éfalse
porqueBoolean(0) === false
.É só 2018, então uma atualização pode ser legal ...
E eu realmente tenho que discordar da resposta aceita . Adia em diferentes navegadores. alguns fazem
forEach
mais rápido, outrosfor-loop
e algunswhile
aqui são uma referência em todos os métodos http://jsben.ch/mW36ee como você pode ver um monte de loop for
for(a = 0; ... )
, vale a pena mencionar que, sem 'var', as variáveis serão definidas globalmente e isso pode afetar drasticamente a velocidade, tornando-a lenta.O dispositivo de Duff roda mais rápido na ópera, mas não no firefox
fonte
2014
While
está de voltaApenas pense lógico.
Veja isso
for
loop tem 3 parâmetrosAgora me diga por que isso deve ser mais rápido do que:
while
tem apenas um parâmetroFiquei totalmente confuso quando o Chrome 28 mostrou que o loop for é mais rápido do que o tempo. Isso deve ter ben algum tipo de
"Todo mundo está usando o loop for, vamos nos concentrar nisso ao desenvolver para o chrome".
Mas agora, em 2014, o loop while está de volta no chrome. é 2 vezes mais rápido, em outros navegadores / antigos sempre foi mais rápido.
Ultimamente eu fiz alguns novos testes. Agora, no ambiente real, esses códigos curtos não valem nada e o jsperf não pode realmente executar corretamente o loop while, porque precisa recriar o array.length que também leva tempo.
você não pode obter a velocidade real de um loop while no jsperf.
você precisa criar sua própria função personalizada e verificar com
window.performance.now()
E sim ... não há como o loop while ser simplesmente mais rápido.
Por exemplo, eu tenho uma cena de tela em que preciso calcular as coordenadas e colisões ... isso é feito entre 10-200 MicroSegundos (não milissegundos). na verdade, leva vários milissegundos para renderizar tudo.
MAS
Existe outra maneira de super desempenho usando o for
loop
em alguns casos ... por exemplo, para copiar / clonar uma matrizObserve a configuração dos parâmetros:
Disse que isso confirma que máquinas como a -
escrevendo que eu estava pensando em torná-lo um pouco mais curto e remover algumas coisas inúteis e escrevi este usando o mesmo estilo:
Mesmo que seja mais curto, parece que usar
i
mais uma vez torna tudo mais lento. É 1/5 mais lento que ofor
loop anterior e o anteriorwhile
.Nota: o
;
é muito importante depois do looo sem{}
Mesmo se eu apenas lhe disser que o jsperf não é a melhor maneira de testar scripts ... eu adicionei esses 2 loops aqui
http://jsperf.com/caching-array-length/40
E aqui está outra resposta sobre o desempenho em javascript
https://stackoverflow.com/a/21353032/2450730
Esta resposta é para mostrar maneiras eficientes de escrever javascript. Portanto, se você não conseguir ler isso, pergunte e você receberá uma resposta ou lerá um livro sobre javascript http://www.ecma-international.org/ecma-262/5.1/
fonte
for
velocidade foi mais rápida que awhile
, e uma vez li no crome-dev que foi exatamente por causa do motivo que você mencionou. Seria apenas uma questão de tempo antes dewhile
recuperar o atraso. A partir desse momento, a lógica da primeira parte da sua resposta se manterá (mais uma vez, sim)! No entanto, as implementações modernas não seguem mais rigidamente todas as etapas especificadas pelo ecma (elas otimizam). Como agora seu motor não é mais o gargalo mais perceptível, agora é possível notar os erros de cache da CPU em loops reversos !http://jsperf.com/caching-array-length/60
A última revisão do teste, que eu preparei (reutilizando um antigo), mostra uma coisa.
O comprimento do cache não é muito importante, mas não prejudica.
Toda primeira execução do teste acima (na aba recém-aberta) fornece os melhores resultados para os últimos 4 trechos (3º, 5º, 7º e 10º nos gráficos) no Chrome, Opera e Firefox no meu Debian Squeeze de 64 bits ( meu hardware de desktop) ) Execuções subseqüentes fornecem resultados bastante diferentes.
As conclusões em termos de desempenho são simples:
!==
vez de<
.shift()
matriz destrutiva também serão eficientes.tl; dr
Atualmente (2011.10) abaixo do padrão parece ser o mais rápido.
Lembre-se de que o cache
arr.length
não é crucial aqui, então você pode apenas testari !== arr.length
e o desempenho não será reduzido, mas você obterá um código mais curto.PS: Eu sei que no snippet com
shift()
seu resultado poderia ser usado em vez de acessar o 0º elemento, mas de alguma forma esqueci que, depois de reutilizar a revisão anterior (que apresentava mal os loops), e mais tarde eu não queria perder os resultados já obtidos.fonte
"Melhor" como no desempenho puro? ou desempenho E legibilidade?
O desempenho puro "melhor" é esse, que usa um cache e o operador de prefixo ++ (meus dados: http://jsperf.com/caching-array-length/189 )
Eu argumentaria que o loop for sem cache é o melhor equilíbrio entre tempo de execução e tempo de leitura do programador. Todo programador que iniciou com C / C ++ / Java não perde um ms tendo que ler este
fonte
len
seja nomeado, é preciso sempre fazer uma análise dupla do primeiro loop. A intenção do segundo ciclo é óbvia.** em cache o comprimento da matriz dentro do loop, alguns segundos serão iludidos. Depende dos itens da matriz, se houver mais itens na matriz, haverá uma grande diferença em relação a Ms de tempo *
**
**
**
**
fonte
Este parece ser o caminho mais rápido de longe ...
Leve em consideração que isso consumirá a matriz, a comerá e não deixará nada ...
fonte
arr.shift();
em vez dearr.pop()
evitar que o inverso da matriz seja evitado.É o ano de 2017 .
Eu fiz alguns testes.
https://jsperf.com/fastest-way-to-iterate-through-an-array/
Parece que o
while
método é o mais rápido no Chrome.Parece que o decréscimo esquerda (
--i
) é muito mais rápido do que os outros (++i
,i--
,i++
) no Firefox.Essa abordagem é o jejum em média. Mas itera a matriz em ordem inversa.
Se a ordem futura for importante, use esta abordagem.
fonte
let
- chave, você está realmente comparando o desempenho da criação do escopo ao invés do desempenho do loop. O usolet i = 0, ii = array.length
em seusfor
loops criará um novo escopo para essas variáveis dentro dofor
bloco. Seuswhile
exemplos não criam um novo escopo para as variáveis dentro dowhile
bloco e é por isso que elas são mais rápidas. Se você usar emvar
vez doslet
loops for, verá como os loops ainda são tão rápidos quanto os de 2017, mas são mais legíveis.var
elet
com o mesmo desempenho - stackoverflow.com/a/32345435/1785975while
ser mais rápido no Chrome". É apenas se estiver usandolet
devido a problemas de desempenho dessa palavra-chave no Chrome. Se você estiver usandovar
ou com outros navegadoresfor
ewhile
for praticamente o mesmo, às vezesfor
é ainda mais rápido, dependendo do benchmark, e é mais compacto e legível.Eu sempre escrevo no primeiro estilo.
Mesmo que um compilador seja inteligente o suficiente para otimizá-lo para matrizes, mas ainda assim se estiver usando o DOMNodeList aqui ou algum objeto complicado com comprimento calculado?
Sei qual é a pergunta sobre matrizes, mas acho que é uma boa prática escrever todos os seus loops em um estilo.
fonte
i ++ é mais rápido que ++ i, --i e i--
Além disso, você pode salvar a última linha fazendo arr [i ++] na última vez que precisar acessar i (mas isso pode ser difícil de depurar).
Você pode testá-lo aqui (com outros testes de loop): http://jsperf.com/for-vs- whilepop/5
fonte
++i
é mais rápido ...Em setembro de 2017, esses testes jsperf mostraram o seguinte padrão com melhor desempenho no Chrome 60:
Alguém é capaz de se reproduzir?
fonte
Eu tentei algumas outras maneiras de iterar uma matriz enorme e descobri que reduzir pela metade o comprimento da matriz e depois iterar as duas metades em um único loop é mais rápido. Essa diferença de desempenho pode ser vista durante o processamento de grandes matrizes .
Alguma comparação de desempenho (usando timer.js) entre o comprimento em cache do loop VS o método acima.
http://jsfiddle.net/tejzpr/bbLgzxgo/
fonte
Outro teste do jsperf.com: http://jsperf.com/ while-reverse-vs-for-cached-length
O loop while reverso parece ser o mais rápido. O único problema é que enquanto (--i) irá parar em 0. Como posso acessar o array [0] no meu loop?
fonte
while (i--)
, a veracidade dei
será testada antes de diminuir, em vez de diminuir e, em seguida, testar a veracidade.Um loop while básico geralmente é o mais rápido. O jsperf.com é um ótimo sandbox para testar esses tipos de conceitos.
https://jsperf.com/fastest-array-loops-in-javascript/24
fonte
O loop while é um pouco mais rápido que o loop for.
Use o loop while
fonte
A abordagem mais rápida é o tradicional for loop. Aqui está uma comparação de desempenho mais abrangente.
https://gists.cwidanage.com/2019/11/how-to-iterate-over-javascript-arrays.html
fonte
A solução mais elegante que conheço é usar o mapa.
fonte
Tente o seguinte:
fonte
A maneira mais rápida de fazer um loop em uma matriz é usando o filtro. O método filter () cria uma nova matriz com todos os elementos que passam no teste implementado pela função fornecida.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
Pela minha experiência, eu sempre prefiro filtros, mapas etc.
fonte
A partir de 2019, o WebWorker tornou-se mais popular; para grandes conjuntos de dados, podemos usar o WebWorker para processar muito mais rapidamente, utilizando totalmente os processadores com vários núcleos.
Também temos o Parallel.js, que facilita o uso do WebWorker no processamento de dados.
fonte