Por que as funções sem efeito são executadas?

4

Todos os idiomas que conheço executam algo como:

i = 0
while i < 100000000
    i += 1

.. e você pode ver que leva um tempo considerável para ser executado.

Por que, porém, os idiomas fazem isso? O único efeito que esse código terá está demorando.

edit: quero dizer dentro de uma função que é chamada

function main(){
    useless()
}
function useless(){
    i = 0
    while i < 100000000
        i += 1
}
    
por mowwwalker 20.06.2012 / 19:56
fonte

9 respostas

18

Em geral, é difícil (isto é, indecidível) provar se algo é um loop de ocupado tolo (que pode ser otimizado) ou um loop infinito (que não pode ser otimizado sem alterar o significado do programa). O código a seguir faz um loop para sempre ou para?

var n = //some positive integer
while(n != 1){
   if(n % 2 == 0)
      n = n/2;
   else
      n = 3*n+1
}

Devido a essa complexidade, a maioria das linguagens de programação desistem de tentar raciocinar muito sobre o programa e, portanto, passam a responsabilidade de não executar loops ocupados para o programador.

    
por 20.06.2012 / 20:24
fonte
18

Obtenha uma implementação melhor. Muitos compiladores de C ++ que eu conheço removeriam códigos muito mais complexos sem efeitos colaterais do que isso.

    
por 20.06.2012 / 19:58
fonte
3

Este código pode não fazer nada como você pensa, mas e se, tomando C # como exemplo, eu tivesse sobrecarregado o operador +.

public static int operator +(int one, int two) {/* implement crazy operation here */}

Na sobrecarga, eu gerava um quadro e dimensionava o operador para sincronizar 60fps.

Esse loop "inútil" agora se tornou um jogo que pára no frame 100000000th. Não é tão inútil heh?

Sua incapacidade de definir claramente "código inútil" é o motivo pelo qual o compilador não consegue lidar com isso.

    
por 21.06.2012 / 12:05
fonte
3

Comumente (e provavelmente o único uso válido para isso) usado em microcontroladores para controlar a temporização com precisão, porém é mais provável que seja escrito em Assembler (ou assembler embutido em um programador C), já que o programador tem controle absoluto sobre o programador. instruções utilizadas, daí o tempo gasto.

    
por 21.06.2012 / 10:28
fonte
2

Há 2 coisas para mencionar aqui. A primeira é que, muitos compiladores como o DeadMG disseram podem otimizar código como este. Como você provavelmente sabe, se o ponto do código fosse levar tempo, isso seria impreciso e dependente da freqüência do processador.

A segunda coisa a salientar é a sua menção de "sem efeito". Pode não ser o que você quer dizer, mas muitos devs (especialmente aqueles que são fãs de programação funcional e seus paradigmas associados) advogam que você deve evitar efeitos colaterais quase inteiramente - isto é, não ter estado externo. De modo geral, programar dessa maneira requer que você retorne algum valor de cada função, portanto, isso não se aplica ao exemplo trivial que você postou - mas a exemplos menos triviais.

    
por 20.06.2012 / 20:10
fonte
2

Para criar uma condição de carga extrema

Um uso do aplicativo Unix sim , que usa uma construção de loop semelhante, é o de exercitar CPU para simular alta carga.

Ele também fornece uma saída "y" contínua para uso com respostas a versões mais antigas de linhas de comando do Unix.

Eu percebo que o aplicativo yes está fornecendo um efeito colateral mensurável e, portanto, não seria otimizado, mas o ponto que estou fazendo é que os loops apertados são rápidos como testes de carga úteis.

    
por 20.06.2012 / 23:55
fonte
1

Como BillMichell sugere em seu comentário, o ponto é consumir tempo, para permitir que algo mais aconteça. A maioria das linguagens modernas tem uma maneira melhor de fazer isso - informando o encadeamento ou processo para sleep ou wait por um período de tempo especificado. Nos velhos e maus dias, isso não era uma opção.

    
por 20.06.2012 / 20:12
fonte
1

2 razões primeiro é que para remover completamente todos os compiladores de código morto precisaria resolver o problema de parada que é impossível e muitos compiladores nem tentam

segundo, por vezes, o programador quer um loop de atraso / ocupado lá por vários motivos (incluindo simplesmente abrandar tudo, então quando o Sr. Boss lhe diz para acelerar, você pode remover um 0 do limite superior)

    
por 21.06.2012 / 01:11
fonte
1

Os primeiros idiomas provavelmente não têm nada a ver com o problema. As definições de idiomas dão o comportamento observável e não consideram a duração como um comportamento observável, exceto para funções de propósito muito especial.

Assim, você está falando sobre a escolha da implementação.

Como um caso documentado, vamos ver o gcc.

No início da documentação do gcc, eles afirmaram que propositalmente não removeram loops vazios, pois provavelmente estavam lá para um propósito de tempo.

No mais recente, eles agora declaram que inverteram sua decisão, pois os loops vazios são mais frequentemente devidos a outras otimizações (que podem remover todo o conteúdo existente) e avisam que loops vazios serão removidos se o gcc puder mostrar isso eles vão terminar.

    
por 21.06.2012 / 11:28
fonte