Encontrei a seguinte anotação de loop em um grande projeto no qual estou trabalhando (pseudocódigo):
var someOtherArray = [];
for (var i = 0, n = array.length; i < n; i++) {
someOtherArray[i] = modifyObjetFromArray(array[i]);
}
O que chamou minha atenção é essa variável "n" extra. Eu nunca vi um for lop escrito dessa maneira antes.
Obviamente, nesse cenário, não há razão para que esse código não possa ser escrito da seguinte maneira (com a qual estou muito acostumado):
var someOtherArray = [];
for (var i = 0; i < array.length; i++) {
someOtherArray[i] = modifyObjetFromArray(array[i]);
}
Mas isso me fez pensar.
Existe um cenário em que escrever um loop for faria sentido? A ideia vem à mente de que o comprimento do "array" pode mudar durante a execução do loop for, mas não queremos um loop além do tamanho original, mas não consigo imaginar esse cenário.
Encolher a matriz dentro do loop também não faz muito sentido, porque provavelmente obteremos OutOfBoundsException.
Existe um padrão de design conhecido em que essa anotação é útil?
Editar Conforme observado por @ Jerry101, o motivo é o desempenho. Aqui está um link para o teste de desempenho que eu criei: http://jsperf.com/ninforloop . Na minha opinião, a diferença não é grande o suficiente, a menos que você esteja repetindo uma variedade muito grande. O código do qual copiei tinha apenas 20 elementos, então acho que a legibilidade neste caso supera a consideração de desempenho.
fonte
n
pode ser mais lenta que a variante utilizada,array.Length
pois o JITter pode não perceber que poderia eliminar as verificações dos limites da matriz.Respostas:
A variável
n
garante que o código gerado não busque o comprimento da matriz para cada iteração.É uma otimização que pode fazer a diferença no tempo de execução, dependendo do idioma usado, se a matriz é realmente um objeto de coleção ou uma "matriz" JavaScript e outros detalhes de otimização.
fonte
n
o loop, o que normalmente é uma coisa boa. Eu o definiria antes do loop apenas se quisesse usá-lo novamente mais tarde.A busca do comprimento da matriz pode ser facilmente "mais cara" do que a ação real sobre a qual você itera.
Portanto, se o conjunto não mudar, consulte o comprimento apenas uma vez.
Não com matrizes, mas com conjuntos de registros provenientes de um servidor sql, vi melhorias drásticas ao não consultar a contagem de registros a cada iteração. (é claro, faça isso apenas se você puder garantir que a matriz ou o conjunto de registros não seja alterado durante esse processo).
fonte
As pessoas que falam sobre desempenho provavelmente estão corretas, por isso foi escrito dessa maneira (a pessoa que escreveu dessa maneira pode não estar correta, pois afeta significativamente o desempenho, mas isso é outra questão).
No entanto, para responder a essa parte da sua pergunta, acho que é mais provável que isso aconteça quando o principal objetivo do loop for modificar o array que ele está repetindo. Considere algo parecido com isto, no pseudo-código:
Claro que existem outras maneiras de escrevê-lo. Nesse caso, eu poderia ter verificado outros mais ao mesmo tempo como se os destinatários aceitavam seus convites e produzido a lista completa de convidados, um convite por vez. Não quero necessariamente combinar essas duas operações, mas não consigo pensar imediatamente em uma razão pela qual isso esteja definitivamente errado e, portanto, esse design é necessário . É uma opção a considerar, ocasionalmente.
Na verdade, acho que a coisa mais errada nesse código é que a associação à
guests
matriz significa coisas diferentes em pontos diferentes do código. Portanto, eu certamente não chamaria isso de "padrão", mas não sei se há defeito suficiente para descartar a possibilidade de fazer algo desse tipo :-)fonte
Se possível, você deve usar um iterador que atravessa todos os elementos da matriz. Você usa a matriz apenas como uma sequência, não como armazenamento de acesso aleatório; portanto, seria óbvio que um iterador que apenas faz um acesso seqüencial seria mais rápido. Imagine o que você acha que uma matriz é na verdade uma árvore binária, mas alguém escreveu um código que determina o "comprimento" contando os elementos e o código que acessa o i-ésimo elemento, também percorrendo o elemento, cada um em O (n ) Um iterador pode ser muito rápido, seu loop será sloooooow.
fonte