Pergunta

Ou é tudo sobre a semântica?

Foi útil?

Solução

Resposta curta: não, eles são exatamente os mesmos

.

acho que poderia, em teoria, dependem do compilador; realmente quebrado se poderia fazer algo um pouco diferente, mas eu ficaria surpreso.

Apenas por diversão, aqui estão duas variantes que compilam até exatamente o mesmo código de montagem para mim usando x86 gcc versão 4.3.3 conforme fornecido com o Ubuntu. Você pode verificar a montagem produzida no binário final com objdump no Linux.

int main()
{
#if 1
    int i = 10;
    do { printf("%d\n", i); } while(--i);
#else
    int i = 10;
    for (; i; --i) printf("%d\n", i);
#endif
}

EDIT: Aqui está um "laranjas com laranjas", enquanto exemplo loop que também compila para baixo para a mesma coisa:

    while(i) { printf("%d\n", i); --i; }

Outras dicas

Se a sua for e while loops de fazer as mesmas coisas, o código de máquina gerado pelo compilador deve ser (quase) o mesmo.

Por exemplo, em alguns testes que fiz há alguns anos atrás,

for (int i = 0; i < 10; i++)
{
...
}

e

int i = 0;
do
{
  ...
  i++;
}
while (i < 10);

geraria exatamente o mesmo código, ou (e Neil apontou nos comentários), com um jmp extra, que não vai fazer uma diferença grande o suficiente no desempenho que se preocupar.

Não há diferença semântica, não precisa haver nenhuma diferença compilado. Mas isso depende do compilador. Então, eu tentei com com g ++ 4.3.2, CC 5.5, e xlc6.

g ++, CC eram idênticas, xlc NÃO ERA

A diferença em xlc era na entrada do circuito inicial.

extern int doit( int );
void loop1( ) {
  for ( int ii = 0; ii < 10; ii++ ) {
    doit( ii );
  }
}

void loop2() {
  int ii = 0; 
  while ( ii < 10 ) {
    doit( ii );
    ii++;
  }
}

XLC OUTPUT

.loop2:                                 # 0x00000000 (H.10.NO_SYMBOL)
    mfspr   r0,LR
    stu     SP,-80(SP)
    st      r0,88(SP)
    cal     r3,0(r0)
    st      r3,64(SP)
    l       r3,64(SP)  ### DIFFERENCE ###
    cmpi    0,r3,10
    bc      BO_IF_NOT,CR0_LT,__L40
...
enter code here
.loop1:                                 # 0x0000006c (H.10.NO_SYMBOL+0x6c)
    mfspr   r0,LR
    stu     SP,-80(SP)
    st      r0,88(SP)
    cal     r3,0(r0)
    cmpi    0,r3,10    ### DIFFERENCE ###
    st      r3,64(SP)
    bc      BO_IF_NOT,CR0_LT,__La8
...

O âmbito da variável no teste do loop while é mais largo do que o âmbito das variáveis ??declaradas no cabeçalho do loop for.

Portanto, se existem implicações de desempenho como um efeito colateral de manter uma variável vivo por mais tempo, em seguida, haverá implicações de desempenho na escolha entre um tempo e um loop for (e não envolvendo o tempo em {} para reduzir o âmbito das suas variáveis).

Um exemplo pode ser uma colecção concorrente que conta o número de iterators referindo-se a ele, e se for mais do que uma iteração existe, aplica-se de bloqueio para impedir a modificação concorrente, mas como um omite optimização do bloqueio se apenas uma iteração refere-se a ele . Se você teve então duas voltas for em uma função usando iteradores com nomes diferentes no mesmo recipiente, o caminho rápido seriam tomadas, mas com dois while laços o caminho lento seriam tomadas. Da mesma forma, pode haver implicações de desempenho se os objetos são grandes (mais tráfego cache), ou os recursos do sistema utilizado. Mas eu não consigo pensar em um exemplo real que eu já vi onde ele iria fazer a diferença.

Os compiladores que optimizam utilizando loop desenrolar provavelmente só irá fazê-lo no caso for-loop.

Ambos são equivalentes. É uma questão de semântica.

A única diferença pode estar no do ... while construção, onde você adiar a avaliação da condição até após do corpo, e assim pode salvar uma avaliação.

i = 1; do { ... i--; } while( i > 0 ); 

em oposição a

for(  i = 1; i > 0; --i )
{ ....
}  

Eu escrevo compiladores. Nós compilar todo o fluxo de controle "estruturado" (if, while, for, switch, do ... while) em ramos condicionais e incondicionais. Em seguida, analisamos o gráfico de controle de fluxo. Desde um compilador C tem que lidar com goto geral de qualquer maneira, é mais fácil de reduzir tudo para instruções de desvio condicional e-filial, em seguida, certifique-se de lidar com esse caso bem. (Compilador A C tem que fazer um bom trabalho não apenas no código escrito à mão, mas também no código gerado automaticamente, o que pode ter muitas, muitas declarações goto.)

No. Se eles estão fazendo coisas equivalentes, eles vão compilar para o mesmo código - como você diz, é sobre semântica. Escolha a que melhor representa o que você está tentando expressar.

Idealmente, deve ser o mesmo, mas, eventualmente, isso depende do seu compilador / intérprete. Para ter certeza, você deve medir ou examinar o código assembly gerado.

A prova de que pode haver uma diferença:. Estas linhas de produção diferente do código de montagem utilizando cc65

for (; i < 1000; ++i);   
while (i < 1000) ++i;

Em Atmel ATmega while () é mais rápido do que para (). Por que isso é explicado em AVR035:. Eficiente C Codificação para AVR

P.S. plataforma original não foi mencionado em questão.

Continuar se comporta de forma diferente em e enquanto : em , que altera o contador, em enquanto , que normalmente não

Para adicionar outra resposta:. Na minha experiência, otimizando software é como um grande, uma barba espessa que está sendo raspado um homem

  • Primeiro você lop-lo em grandes pedaços com uma tesoura (membros inteiros podar a árvore chamada).
  • Em seguida, você torná-lo curto com um clipper elétrico (algoritmos Tweak).
  • Finalmente, você cortá-la com uma navalha para se livrar da última pouco (otimização de baixo nível).

A última é onde a diferença entre for() e poder while(), mas provavelmente não vai, fazer a diferença.

P.S. Os programadores que eu conheço (que são todos muito bons, e eu suspeito que são uma amostra representativa), basicamente, ir para ele de outra direção.

Eles são os mesmos, tanto quanto o desempenho vai. I tendem a utilização while quando esperando por uma mudança de estado (tal como a espera de uma memória intermédia para ser cheio) e for quando o processamento de um número de objectos discretos (tais como passando por cada item numa colecção).

Há uma diferença em alguns casos.

Se você está no ponto onde que as questões de diferença, você quer necessidade de escolher um algoritmo de melhor ou começar a codificação em linguagem assembly. Confie em mim, a codificação em assembly é preferível fixar a sua versão do compilador.

É while() mais rápido / mais lento do que for()? Vamos rever algumas coisas sobre otimização:

  • Compiler-escritores trabalhar muito duro para ciclos de barbear por ter menos chamadas para saltar, comparar, incremento, e os outros tipos de instruções que eles geram.

  • instruções de chamada, por outro lado, consumir muitas magnitudes mais ciclos, mas o compilador é quase impotente para fazer qualquer coisa para remover aqueles.

  • Como programadores, escrevemos muitas chamadas de função, alguns porque nós pretendemos, alguns porque é preguiçoso, e alguns porque o compilador colocava-os dentro sem ser óbvio.

  • Na maioria das vezes, isso não importa, porque o hardware é tão rápido, e os nossos empregos são tão pequenas, que o computador é como um cão beagle que Wolfes sua comida e implora por mais.

  • Às vezes, porém, o trabalho é grande o suficiente para que o desempenho é um problema.

  • O que fazemos então? Onde é a recompensa maior?

    • Obtendo o compilador barbear alguns ciclos off laços e tal?
    • função chamadas constatação de que não o fazem -realmente -? necessidade de ser feito tanto
  • O compilador não pode fazer o último. Somente nós os programadores podem.

  • Precisamos aprender ou ser ensinados a fazer isso. Ele não vem naturalmente. Estamos congenitamente inclinado a fazer suposições erradas e depois apostar neles. Obtenção de melhores algoritmos é um começo, mas apenas um começo. Nossos professores precisam ensinar isso, se de fato que sei como.

  • Profilers são um começo. eu faço isso.

O apócrifo Citação de Willie Sutton quando perguntado Por que você roubar bancos :
Porque é onde está o dinheiro.

Se você quiser economizar ciclos, descobrir onde eles estão.

estilo Provavelmente, só codificação.

  • para se você sabe o número de iterações.
  • enquanto que se você não sabe o número de iterações.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top