Se você tivesse que repetir um loop 7 vezes, usaria:
for (int i = 0; i < 7; i++)
ou:
for (int i = 0; i <= 6; i++)
Há duas considerações:
- desempenho
- legibilidade
Para desempenho, estou assumindo Java ou C #. Importa se "menor que" ou "menor ou igual a" é usado? Se você tiver informações sobre um idioma diferente, indique qual.
Para facilitar a leitura, estou assumindo matrizes baseadas em 0.
UPD: Minha menção a matrizes baseadas em 0 pode ter confundido as coisas. Eu não estou falando sobre a iteração através de elementos da matriz. Apenas um loop geral.
Há um bom ponto abaixo sobre o uso de uma constante na qual explicaria qual é esse número mágico. Então, se eu tivesse " int NUMBER_OF_THINGS = 7
" então " i <= NUMBER_OF_THINGS - 1
" pareceria estranho, não seria?
performance
conventions
readability
Eugene Katz
fonte
fonte
Respostas:
O primeiro é mais idiomático . Em particular, indica (no sentido 0) o número de iterações. Ao usar algo baseado em 1 (por exemplo, JDBC, IIRC), fico tentado a usar <=. Assim:
Eu esperaria que a diferença de desempenho fosse insignificantemente pequena no código do mundo real.
fonte
Os dois loops repetem 7 vezes. Eu diria que um com 7 é mais legível / claro, a menos que você tenha uma boa razão para o outro.
fonte
Lembro-me dos meus dias em que fizemos a Assembléia do 8086 na faculdade, que era mais eficiente:
pois houve uma operação JNS que significa Jump if No Sign. Usar isso significava que não havia pesquisa de memória após cada ciclo para obter o valor de comparação e também nenhuma comparação. Atualmente, a maioria dos compiladores otimiza o uso do registro para que a memória não seja mais importante, mas você ainda recebe uma comparação desnecessária.
A propósito, colocar 7 ou 6 no seu loop é introduzir um " número mágico ". Para melhor legibilidade, você deve usar uma constante com um Nome revelador de intenção. Como isso:
EDIT: As pessoas não estão recebendo a coisa de montagem, portanto é obviamente necessário um exemplo mais completo:
Se fizermos por (i = 0; i <= 10; i ++), você precisará fazer o seguinte:
Se fizermos por (int i = 10; i> -1; i--), então você pode se safar com isso:
Acabei de verificar e o compilador C ++ da Microsoft não faz essa otimização, mas o faz se você:
Portanto, a moral é que se você estiver usando o Microsoft C ++ †, e subir ou descer não faz diferença, para obter um loop rápido, você deve usar:
em vez de qualquer um destes:
Mas, francamente, obter a legibilidade de "for (int i = 0; i <= 10; i ++)" é normalmente muito mais importante do que perder um comando do processador.
† Outros compiladores podem fazer coisas diferentes.
fonte
7-i
que será necessário para eliminar todas as otimizações que você obtém da contagem inversa.Eu sempre uso <array.length porque é mais fácil ler do que <= array.length-1.
também tendo <7 e considerando que está começando com um índice 0, deve ser intuitivo que o número seja o número de iterações.
fonte
Visto de um ponto de vista otimizador, não importa.
Visto do ponto de vista do estilo de código, eu prefiro <. Razão:
é muito mais legível do que
também <fornece o número de iterações imediatamente.
Outro voto para <é que você pode evitar muitos erros acidentais de um por um.
fonte
@ Chris, Sua afirmação sobre o .Length ser caro no .NET é realmente falsa e, no caso de tipos simples, é exatamente o oposto.
é realmente mais lento que
O posterior é um caso otimizado pelo tempo de execução. Como o tempo de execução pode garantir, i é um índice válido na matriz, nenhuma verificação de limites é feita. No primeiro, o tempo de execução não pode garantir que eu não tenha sido modificado antes do loop e força verificações de limites na matriz para todas as pesquisas de índice.
fonte
.lenght
OR.size
. Não tenho certeza, mas não estou confiante, mas quero ter certeza.Não faz diferença efetiva quando se trata de desempenho. Portanto, eu usaria o que for mais fácil de entender no contexto do problema que você está resolvendo.
fonte
Eu prefiro:
Eu acho que isso se traduz mais prontamente em "iterando através de um loop 7 vezes".
Não tenho certeza das implicações de desempenho - suspeito que quaisquer diferenças sejam compiladas.
fonte
No Java 1.5, você pode simplesmente fazer
portanto, para o caso de matriz, você não precisa se preocupar.
fonte
Não acho que exista diferença de desempenho. A segunda forma é definitivamente mais legível, porém, você não precisa subtrair mentalmente uma para encontrar o último número da iteração.
Edição: Eu vejo outros discordam. Para mim, pessoalmente, gosto de ver os números de índice reais na estrutura do loop. Talvez seja porque é mais uma reminiscência da
0..6
sintaxe de Perl , que eu sei que é equivalente(0,1,2,3,4,5,6)
. Se eu vir um 7, tenho que verificar o operador ao lado para ver se, de fato, o índice 7 nunca é atingido.fonte
Eu diria que use a versão "<7" porque é isso que a maioria das pessoas lerá - portanto, se as pessoas estiverem lendo o seu código, elas poderão interpretá-lo incorretamente.
Eu não me preocuparia se "<" é mais rápido que "<=", basta procurar legibilidade.
Se você deseja aumentar a velocidade, considere o seguinte:
Para aumentar o desempenho, você pode reorganizá-lo levemente para:
Observe a remoção de GetCount () do loop (porque isso será consultado em cada loop) e a alteração de "i ++" para "++ i".
fonte
Em C ++, prefiro usar
!=
, que é utilizável com todos os contêineres STL. Nem todos os iteradores de contêineres STL são menos que comparáveis.fonte
Edsger Dijkstra escreveu um artigo sobre isso em 1982, onde ele defende <<i i upper:
fonte
Primeiro, não use 6 ou 7.
Melhor usar:
Nesse caso, é melhor do que usar
Ainda melhor (Java / C #):
E ainda melhor (C #)
O loop reverso é realmente mais rápido, mas, como é mais difícil de ler (se não for feito por outros programadores), é melhor evitar isso. Especialmente em C #, Java ...
fonte
Eu concordo com a multidão dizendo que o 7 faz sentido nesse caso, mas eu acrescentaria que no caso em que o 6 é importante, digamos que você queira deixar claro que está agindo apenas em objetos até o sexto índice, depois o <= é melhor, pois facilita a visualização dos 6.
fonte
Lá na faculdade, lembro-me de algo sobre essas duas operações serem semelhantes em tempo de computação na CPU. Claro, estamos falando no nível da montagem.
No entanto, se você estiver falando de C # ou Java, eu realmente não acho que um será um aumento de velocidade em relação ao outro. Os poucos nanossegundos que você ganha provavelmente não valem nenhuma confusão que você apresentar.
Pessoalmente, eu criaria o código que faz sentido do ponto de vista da implementação de negócios e garantiria uma leitura fácil.
fonte
Isso se enquadra diretamente na categoria "Fazendo o código errado parecer errado" .
Em linguagens de indexação baseadas em zero, como Java ou C #, as pessoas estão acostumadas a variações na
index < count
condição. Assim, alavancar essa convenção padrão tornaria os erros off-a-one mais óbvios.Em relação ao desempenho: qualquer bom compilador que valha o espaço ocupado pela memória deve renderizar, como um não problema.
fonte
Como um pequeno aparte, ao percorrer uma matriz ou outra coleção em .Net, acho
para ser mais legível do que o loop for numérico. Obviamente, isso pressupõe que o próprio contador Int não seja usado no código do loop. Não sei se há uma alteração no desempenho.
fonte
Existem muitas boas razões para escrever i <7. Ter o número 7 em um loop que itera 7 vezes é bom. O desempenho é efetivamente idêntico. Quase todo mundo escreve i <7. Se você está escrevendo para facilitar a leitura, use o formulário que todos reconhecerão instantaneamente.
fonte
Eu sempre preferi:
fonte
Criar o hábito de usar <o tornará consistente para você e o leitor quando estiver iterando através de uma matriz. Será mais simples para todos ter uma convenção padrão. E se você estiver usando um idioma com matrizes baseadas em 0, <é a convenção.
Isso quase certamente importa mais do que qualquer diferença de desempenho entre <e <=. Procure primeiro a funcionalidade e a legibilidade e depois otimize.
Outra observação é que seria melhor ter o hábito de fazer ++ i em vez de i ++, pois a busca e o incremento requerem um temporário e o incremento e a busca não. Para números inteiros, seu compilador provavelmente otimizará a ausência temporária, mas se seu tipo de iteração for mais complexo, talvez não seja possível.
fonte
Não use números mágicos.
Por que é 7? (ou 6 para esse assunto).
use o símbolo correto para o número que deseja usar ...
Nesse caso, acho melhor usar
fonte
Os operadores '<' e '<=' são exatamente o mesmo custo de desempenho.
O operador '<' é um padrão e mais fácil de ler em um loop baseado em zero.
Usar ++ i em vez de i ++ melhora o desempenho em C ++, mas não em C # - não sei sobre Java.
fonte
Como as pessoas observaram, não há diferença em nenhuma das duas alternativas mencionadas. Apenas para confirmar isso, fiz alguns testes comparativos simples em JavaScript.
Você pode ver os resultados aqui . O que não está claro disso é que, se eu trocar a posição dos 1º e 2º testes, os resultados desses 2 testes forem trocados, isso é claramente um problema de memória. No entanto, o terceiro teste, em que eu inverto a ordem da iteração, é claramente mais rápido.
fonte
Como todo mundo diz, é habitual usar iteradores indexados 0, mesmo para coisas fora das matrizes. Se tudo começa
0
e termina emn-1
, e os limites inferiores são sempre<=
e os limites superiores são sempre<
, há muito menos pensamento que você deve fazer ao revisar o código.fonte
Ótima pergunta. Minha resposta: use o tipo A ('<')
i < strlen(s)
do que o índice do último elemento, portanto a uniformidade é importante.Outro problema é com toda essa construção.
i
aparece 3 vezes nele, para que possa ser digitado incorretamente. A construção do loop for diz como fazer em vez do que fazer . Sugiro adotar isso:BOOST_FOREACH(i, IntegerInterval(0,7))
Isso é mais claro, compila exatamente as mesmas instruções ASM, etc. Solicite o código de IntegerInterval, se desejar.
fonte
Tantas respostas ... mas acredito que tenho algo a acrescentar.
Minha preferência é que os números literais mostrem claramente quais valores "i" receberão no loop . Portanto, no caso de iterar por uma matriz baseada em zero:
for (int i = 0; i <= array.Length - 1; ++i)
E se você está repetindo, não repetindo uma matriz, contar de 1 a 7 é bastante intuitivo:
for (int i = 1; i <= 7; ++i)
A legibilidade supera o desempenho até o seu perfil, pois provavelmente você não sabe o que o compilador ou o tempo de execução fará com o seu código até então.
fonte
Você também pode usar
!=
. Dessa forma, você obterá um loop infinito se cometer um erro na inicialização, fazendo com que o erro seja percebido mais cedo e quaisquer problemas que causem sejam limitados a ficarem presos no loop (em vez de ter um problema muito mais tarde e não encontrar isto).fonte
Acho que ambos estão bem, mas quando você escolher, atenha-se a um ou ao outro. Se você está acostumado a usar <=, tente não usar <e vice-versa.
Eu prefiro <=, mas em situações em que você está trabalhando com índices que começam em zero, provavelmente tentaria usar <. É tudo preferência pessoal embora.
fonte
Estritamente do ponto de vista lógico, você deve pensar que
< count
seria mais eficiente do que<= count
pelo motivo exato que<=
também testará a igualdade.fonte