Perché vengono eseguite le funzioni senza effetto?

4

Tutte le lingue che conosco eseguono qualcosa del tipo:

i = 0
while i < 100000000
    i += 1

.. e puoi vedere che richiede una notevole quantità di tempo per l'esecuzione.

Perché, però, le lingue fanno questo? L'unico effetto che questo codice avrà richiede tempo.

modifica: intendo all'interno di una funzione che si chiama

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

9 risposte

18

In generale, è difficile (cioè indecidibile) dimostrare se qualcosa è un loop occupato da stupidi (che potrebbe essere ottimizzato) o un ciclo infinito (che non può essere ottimizzato senza modificare il significato del programma). Il codice seguente si interrompe per sempre o si ferma?

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

A causa di questa complessità, la maggior parte dei linguaggi di programmazione rinuncia al tentativo di ragionare troppo sul programma e quindi passa la responsabilità di non far tornare i loop occupati al programmatore.

    
risposta data 20.06.2012 - 20:24
fonte
18

Ottieni un'implementazione migliore. Molti compilatori C ++ che conosco rimuovono codice molto più complesso senza effetti collaterali di questo.

    
risposta data 20.06.2012 - 19:58
fonte
3

Questo codice potrebbe non fare nulla come credi, ma cosa succede se, prendendo C # come esempio, ho sovraccaricato l'operatore +.

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

Nel sovraccarico, genererei un frame e ridimensiono l'operatore da sincronizzare per 60fps.

Questo ciclo "inutile" è ora diventato un gioco che si ferma al frame 100000000th. Non è così inutile heh?

La tua incapacità di definire chiaramente "codice inutile" è il motivo per cui il compilatore non può occuparsene.

    
risposta data 21.06.2012 - 12:05
fonte
3

Comunemente (e probabilmente l'unico uso valido per questo) utilizzato nei microcontrollori per controllare accuratamente i tempi, tuttavia è più probabile che sia scritto in Assembler (o assemblatore inline in un programmatore C) poiché il programmatore ha quindi il controllo assoluto sul istruzioni utilizzate, quindi il tempo impiegato.

    
risposta data 21.06.2012 - 10:28
fonte
2

Ci sono 2 cose da menzionare qui. La prima è che, molti compilatori come ha detto DeadMG potrebbero ottimizzare il codice come questo. Come probabilmente saprai, se il punto del codice era prendere tempo, allora questo è inaccurato e dipende dalla frequenza del processore.

La seconda cosa da sottolineare è la tua menzione di "effect-less". Potrebbe non essere ciò che intendi, ma molti sviluppatori (specialmente quelli che sono fan della programmazione funzionale e dei relativi paradigmi) sostengono che dovresti evitare quasi completamente gli effetti collaterali, vale a dire non avere uno stato esterno. In generale, programmare in questo modo richiede che tu restituisca un valore da ogni funzione, quindi non si applica all'esempio banale che hai postato, ma a esempi meno banali.

    
risposta data 20.06.2012 - 20:10
fonte
2

Per creare una condizione di caricamento estremo

Un uso dell'applicazione Unix yes , che utilizza un costrutto di loop simile, è di esercitare il CPU per simulare un carico elevato.

Fornisce inoltre un output "y" continuo da utilizzare con le risposte a versioni precedenti delle righe di comando di Unix.

Mi rendo conto che l'applicazione yes fornisce un effetto collaterale misurabile e quindi non viene ottimizzata, ma il punto che sto facendo è che i loop veloci e stretti servono come test di carico utili.

    
risposta data 20.06.2012 - 23:55
fonte
1

Come suggerisce @BillMichell nel suo commento, il punto è quello di consumare tempo, presumibilmente per consentire che accada qualcos'altro. La maggior parte dei linguaggi moderni ha un modo migliore per farlo: comunicare il thread o il processo a sleep o wait per un periodo di tempo specificato. Nei vecchi tempi, quella non era un'opzione.

    
risposta data 20.06.2012 - 20:12
fonte
1

2 motivi per primi è che per rimuovere completamente tutti i compilatori di codice morto è necessario risolvere il problema di interruzione che è impossibile e molti compilatori non ci provano nemmeno

a volte il programmatore vuole un ciclo di delay / busy per vari motivi (incluso semplicemente rallentare tutto in modo che quando Mr. Boss ti dice di accelerarlo puoi rimuovere uno 0 dal limite superiore)

    
risposta data 21.06.2012 - 01:11
fonte
1

Le prime lingue probabilmente non hanno nulla a che fare con il problema. Le definizioni dei linguaggi danno il comportamento osservabile e non considerano la durata come un comportamento osservabile ad eccezione di funzioni molto speciali.

Quindi parli della scelta dell'implementazione.

Come caso documentato, esaminiamo gcc.

Nella prima documentazione di gcc, hanno dichiarato di non aver rimosso intenzionalmente i loop vuoti perché probabilmente erano lì per uno scopo temporale.

In uno più recente, ora dichiarano di aver invertito la loro decisione in quanto i loop vuoti sono ora più spesso dovuti ad altre ottimizzazioni (che possono rimuovere tutto il contenuto esistente) e avvertono che i loop vuoti verranno rimossi se gcc è in grado di mostrare che termineranno.

    
risposta data 21.06.2012 - 11:28
fonte

Leggi altre domande sui tag