Usando loops incrementados com prefixo em C #

4

De volta quando comecei a programar na faculdade, um amigo me incentivou a usar o operador de incremento de prefixo ++i em vez do postfix i++ , citando que havia uma pequena chance de melhor desempenho sem chance real de desvantagem. Eu percebo que isso é verdade em C ++, e se tornou um hábito geral que eu continuo a fazer.

Sou levado a acreditar que faz pouca ou nenhuma diferença quando usado em um loop em C #, independentemente do tipo de dados. Aparentemente, o operador ++ não pode ser substituído. No entanto, gosto mais da aparência e não vejo uma desvantagem direta para ela.

Ele surpreendeu um colega de trabalho há pouco, entretanto, ele fez a (bastante lógica) suposição de que meu loop terminaria cedo como resultado. Ele é um programador autodidata e aparentemente nunca encontrou a convenção do C ++. Isso me fez questionar se o comportamento equivalente dos operadores de incremento e decremento antes e depois da correção em loops é bem conhecido o suficiente.

É aceitável continuar usando ++i em construções de loop por causa da preferência de estilo, mesmo que não tenha nenhum benefício real de desempenho? Ou é provável que cause confusão entre outros programadores?

  • Nota: Isso pressupõe que a convenção ++i seja usada consistentemente em todo o código.
por KChaloux 11.09.2012 / 21:56
fonte

6 respostas

11

Eu acho que você deve ficar com as convenções que seus colegas de trabalho estão acostumados. O princípio da menor surpresa. Você não quer se sentar e descobrir por que uma operação simples é escrita de maneira incomum sem nenhum motivo, então por que o próximo cara que está lendo seu código?

    
por 11.09.2012 / 22:00
fonte
6

Não otimizado, i++ faz uma cópia, então j = i++ é traduzido para:

iTemp = i;
i = i + 1;
j = iTemp;

Considerando que j = ++i se traduz em:

i = i + 1;
j = i;

Essa cópia extra em uma variável temporária é o que causa o desempenho teórico atingido com o pós-incremento. No entanto, como o novo valor de i não depende de j , ele pode ser otimizado para:

j = i;
i = i + 1;

Que, salvo qualquer esquisitice de pipeline, tem exatamente o mesmo tempo de execução que a versão de pré-incremento. Acontece que há muito poucas circunstâncias do mundo real em que uma otimização de compilador semelhante não é possível, portanto, há praticamente nenhuma razão para escolher o pré-incremento por motivos de otimização. Incrementos autônomos, como em um loop for , são ainda mais fáceis de otimizar até a mesma instrução.

Em outras palavras, siga a convenção de codificação, a menos que seja sintaticamente significativa. Mas não faz mal educar seus colegas se o único motivo pelo qual eles não o utilizam é baseado em uma compreensão errônea de como for loops funcionam.

    
por 11.09.2012 / 22:50
fonte
3

++i e i++ são operações diferentes.

Verifique este link dá um exemplo melhor do que eu. mas eu estava no caminho certo.

int i = 1;

Console.WriteLine(++i); // <-- will output 2



i = 1; // <-- reset i

Console.WriteLine(i++); // <-- will output 1
    
por 11.09.2012 / 22:19
fonte
3

A boa prática é usar a convenção de codificação com a qual os membros / faculdades da sua equipe estão de acordo. Não importa realmente como você decidiu fazer isso, na medida em que funciona e implementado de forma inconstante. Manter o código tão simples e tão limpo (princípio KISS) deve ser o objetivo principal.

É muito mais importante ter um estilo consistente de codificação em grandes projetos para facilitar a manutenção em fases posteriores.

Aqui você é um link de diretrizes da MS - Convenções de Codificação C # (Guia de Programação C #)

    
por 11.09.2012 / 22:07
fonte
1

Eu diria que isso depende exatamente do que você quer dizer com "preferência de estilo". Se você quer dizer que deseja usar "++ i" em todos os lugares incluindo loops como for(i=0; i<x; ++i) , tudo bem. Se por outro lado você quiser usá-lo especificamente em loops enquanto em outro lugar usando i++ ou i+=1 (ou vice-versa), então essa é uma idéia terrível, você deve ser consistente durante todo o programa.

Contanto que você seja consistente e não o esteja usando em uma expressão de comparação ou várias vezes em uma chamada de método, isso não deve ser uma surpresa para ninguém. Em particular, o loop for é

  1. Atribuição
  2. Comparação
  3. Corpo, if, true e Finally
  4. Incremento

Contanto que você não esteja fazendo seu incremento em 1, 2 ou 3, não deve haver surpresas.

Por outro lado, se em algum momento você usar pós-incremento e, às vezes, pré-incremento, ou fazê-lo de maneira não-padrão f(i++, ++i); , você fará uma pausa e provavelmente cometerá um erro você mesmo ou levar alguém a cometer um erro.

Note que se você escolher ++ i, eu recomendo que você nunca faça isso if(++i<x) ...

    
por 12.09.2012 / 04:07
fonte
0

É verdade que i++ e ++i são operações diferentes. Eles têm o mesmo efeito colateral (modificando o valor armazenado de i ), mas produzem valores diferentes e como resposta de Karl Bielefeldt indica que uma implementação não otimizada de i++ pode ter que armazenar o valor anterior de i em um temporário.

Mas se você os estiver usando em um contexto onde o resultado não é usado, não deve haver diferença alguma.

Por exemplo, em um loop de estilo C, a terceira expressão no cabeçalho do loop é avaliada apenas por seus efeitos colaterais; qualquer valor que ele produz é discretamente descartado. Esses dois loops:

for (i = 0; i < COUNT; i ++) {
    // ...
}

for (i = 0; i < COUNT; ++ i) {
    // ...
}

tem semântica idêntica, e se o seu compilador não gerar código idêntico, ou pelo menos equivalente, você provavelmente encontrará um compilador melhor.

Portanto, neste contexto, a escolha entre i ++ e ++ i deve ser puramente de estilo. Se você tem um padrão de codificação, siga-o. Se você não fizer isso, apenas seja consistente.

Se você estiver usando i ++ ou ++ i em um contexto em que o resultado é usado, o desempenho não será um fator; use o que lhe der a resposta que você precisa. Ou considere se seu código pode ser mais limpo se você reorganizá-lo para não usar o resultado de i ++ ou ++ i .

    
por 29.09.2012 / 01:24
fonte