Quale è più veloce: while (1) o while (2)?


11 Answers

Sì, while(1) è molto più veloce di while(2) , per un umano da leggere! Se vedo while(1) in una base di codice non familiare, so immediatamente che cosa l'autore intendeva, e i miei bulbi oculari possono continuare alla riga successiva.

Se vedo while(2) , probabilmente mi fermerò nelle mie tracce e cercherò di capire perché l'autore non ha scritto while(1) . Il dito dell'autore è scivolato sulla tastiera? I manutentori di questa base di codici usano while(n) come un oscuro meccanismo di commento per far apparire i loop diversi? È una soluzione approssimativa per un avviso spuria in qualche strumento di analisi statica rotto? O è questo un indizio che sto leggendo il codice generato? E 'un insetto derivante da un male-trovato find-and-replace-all, o una brutta unione, o un raggio cosmico? Forse questa linea di codice dovrebbe fare qualcosa di drammaticamente diverso. Forse doveva leggere while(w) o while(x2) . È meglio che trovi l'autore nella cronologia del file e invii loro un'e-mail "WTF" ... e ora ho infranto il mio contesto mentale. Il while(2) potrebbe consumare diversi minuti del mio tempo, quando while(1) avrebbe richiesto una frazione di secondo!

Sto esagerando, ma solo un po '. La leggibilità del codice è molto importante. E vale la pena menzionarlo in un'intervista!

Question

Questa è stata una domanda di intervista fatta da un senior manager.

Quale è più veloce?

while(1) {
    // Some code
}

o

while(2) {
    //Some code
}

Ho detto che entrambi hanno la stessa velocità di esecuzione, come l'espressione dentro while dovrebbe finalmente valutare il true o il false . In questo caso, entrambi valutano true e non ci sono istruzioni condizionali extra all'interno della condizione while . Quindi, entrambi avranno la stessa velocità di esecuzione e io preferisco mentre (1).

Ma l'intervistatore ha detto con sicurezza: "Controlla le basi, while(1) è più veloce di while(2) ." (Non stava mettendo alla prova la mia fiducia)

È vero?

Vedi anche: "for (;;)" più veloce di "while (TRUE)"? Se no, perché la usano?




Apetta un minuto. L'intervistatore, ha l'aspetto di questo ragazzo?

È già abbastanza brutto che l'intervistatore stesso abbia fallito questa intervista, e se altri programmatori di questa compagnia avessero "superato" questo test?

No. Valutare le affermazioni 1 == 0 e 2 == 0 dovrebbe essere ugualmente veloce. Potremmo immaginare implementazioni del compilatore scadenti in cui uno potrebbe essere più veloce dell'altro. Ma non c'è una buona ragione per cui uno dovrebbe essere più veloce dell'altro.

Anche se c'è qualche circostanza oscura quando la richiesta è vera, i programmatori non dovrebbero essere valutati sulla base della conoscenza di curiosità oscure (e in questo caso raccapriccianti). Non preoccuparti di questa intervista, la mossa migliore qui è quella di andarsene.

Disclaimer: NON è un cartone originale di Dilbert. Questo è semplicemente un mashup .




La spiegazione più probabile per la domanda è che l'intervistatore pensa che il processore controlla i singoli bit dei numeri, uno per uno, finché non raggiunge un valore diverso da zero:

1 = 00000001
2 = 00000010

Se "è zero?" l'algoritmo parte dal lato destro del numero e deve controllare ogni bit finché non raggiunge un bit diverso da zero, while(1) { } il ciclo while(1) { } dovrebbe controllare il doppio dei bit per iterazione del while(2) { } ciclo continuo.

Ciò richiede un modello mentale molto sbagliato su come funzionano i computer, ma ha una sua logica interna. Un modo per controllare sarebbe chiedere se while(-1) { } o while(3) { } sia ugualmente veloce, o se while(32) { } sia ancora più lento .




Penso che l'indizio si trovi in ​​"richiesta da un senior manager". Questa persona ha ovviamente smesso di programmare quando è diventato un manager e poi gli è servito diversi anni per diventare un senior manager. Non ha mai perso interesse per la programmazione, ma non ha mai scritto una riga da quei giorni. Quindi il suo riferimento non è "nessun compilatore decente là fuori", come alcune risposte menzionano, ma "il compilatore questa persona ha lavorato con 20-30 anni fa".

A quel tempo, i programmatori trascorrevano una considerevole percentuale del loro tempo a provare vari metodi per rendere il loro codice più veloce ed efficiente in quanto il tempo di CPU del "minicomputer centrale" era così prezioso. Come le persone che scrivevano compilatori. Immagino che il compilatore unico e solo la sua azienda reso disponibile in quel momento sia ottimizzato sulla base di "affermazioni frequentemente incontrate che possono essere ottimizzate" e abbia preso un po 'di scorciatoia quando ha incontrato un po' (1) e valutato tutto altro, compreso un po '(2). Avere avuto una tale esperienza potrebbe spiegare la sua posizione e la sua fiducia in essa.

L'approccio migliore per farti assumere è probabilmente quello che consente al senior manager di lasciarsi trasportare e darti lezioni di 2-3 minuti sui "bei vecchi tempi della programmazione" prima che tu possa guidarlo senza problemi verso la prossima materia. (Il buon tempismo è importante qui - troppo veloce e stai interrompendo la storia - troppo lento e sei etichettato come qualcuno con una concentrazione insufficiente). Digli alla fine dell'intervista che saresti molto interessato a saperne di più su questo argomento.




Per questa domanda, dovrei aggiungere che ricordo che Doug Gwyn del C Committee ha scritto che alcuni dei primi compilatori C senza il pass ottimizzatore avrebbero generato un test in assembly per un while(1) (confrontandolo con for(;;) che wouldn ce l'ho).

Risponderei all'intervistatore dando questa nota storica e poi dire che anche se sarei molto sorpreso da qualsiasi compilatore, un compilatore potrebbe avere:

  • senza ottimizzatore, il compilatore genera un test per entrambi while(1) e while(2)
  • con il passaggio dell'ottimizzatore il compilatore viene istruito per ottimizzare (con un salto incondizionato) per tutto while(1) perché sono considerati come idiomatici. Questo lascerebbe il while(2) con un test e quindi fa una differenza di prestazioni tra i due.

Naturalmente aggiungerei all'intervistatore che non considerando while(1) e while(2) lo stesso costrutto è un segno di ottimizzazione di bassa qualità in quanto sono costrutti equivalenti.




Vedere così tante persone approfondire questo problema, mostra esattamente perché questo potrebbe benissimo essere un test per vedere quanto velocemente si vogliono ottimizzare le cose in micro .

La mia risposta sarebbe; non importa molto, preferisco concentrarmi sul problema aziendale che stiamo risolvendo. Dopotutto, è per quello che pagherò.

Inoltre, opterei per while(1) {} perché è più comune, e gli altri compagni di squadra non avrebbero bisogno di dedicare del tempo a capire perché qualcuno andrebbe per un numero superiore a 1.

Ora vai a scrivere un codice. ;-)




Mi sembra che questa sia una di quelle domande sul colloquio comportamentale mascherate da una domanda tecnica. Alcune aziende lo fanno - porranno una domanda tecnica che dovrebbe essere abbastanza facile per qualsiasi programmatore competente a rispondere, ma quando l'intervistato dà la risposta corretta, l'intervistatore dirà loro che hanno torto.

La compagnia vuole vedere come reagirai in questa situazione. Ti siedi lì in silenzio e non spingere la tua risposta è corretta, a causa di dubbi o di timore di turbare l'intervistatore? O sei disposto a sfidare una persona con autorità che sai essere sbagliata? Vogliono vedere se sei disposto a difendere le tue convinzioni e se riesci a farlo in modo discreto e rispettoso.




Ecco un problema: se in realtà scrivi un programma e ne misurhi la velocità, la velocità di entrambi i loop potrebbe essere diversa! Per un ragionevole confronto:

unsigned long i = 0;
while (1) { if (++i == 1000000000) break; }

unsigned long i = 0;
while (2) { if (++i == 1000000000) break; }

con qualche codice aggiunto che stampa il tempo, alcuni effetti casuali come il posizionamento del loop all'interno di una o due linee della cache potrebbero fare la differenza. Un ciclo potrebbe per pura casualità essere completamente all'interno di una linea di cache, o all'inizio di una linea di cache, o potrebbe scavalcare due linee di cache. E di conseguenza, qualunque sia l'affermazione dell'intervistatore più veloce potrebbe effettivamente essere il più veloce - per coincidenza.

Scenario peggiore: un compilatore ottimizzante non capisce cosa fa il ciclo, ma capisce che i valori prodotti quando il secondo ciclo viene eseguito sono gli stessi prodotti dal primo. E generare il codice completo per il primo ciclo, ma non per il secondo.




A giudicare dal tempo e dallo sforzo che le persone hanno speso per testare, provare e rispondere a questa domanda molto semplice, Id dice che entrambi sono stati fatti molto lentamente ponendo la domanda.

E quindi per trascorrere ancora più tempo su di esso ...

"while (2)" è ridicolo, perché,

"while (1)" e "while (true)" sono storicamente utilizzati per creare un ciclo infinito che si aspetta che la "pausa" venga chiamata ad un certo punto all'interno del ciclo in base a una condizione che si verificherà certamente.

Il "1" è semplicemente lì per valutare sempre il vero e quindi, per dire "while (2)" è sciocco come dire "while (1 + 1 == 2)" che valuterà anche il vero.

E se vuoi essere completamente sciocco usa solo:

while (1 + 5 - 2 - (1 * 3) == 0.5 - 4 + ((9 * 2) / 4)) {
    if (succeed())
        break;
}

Mi piace pensare che il tuo coder abbia fatto un errore di battitura che non ha influito sul funzionamento del codice, ma se ha intenzionalmente usato il "2" per essere strano, allora lo licenzierà prima che metta in sordina tutto il tuo codice rendendolo difficile leggi e lavora con.




Questo dipende dal compilatore.

Se ottimizza il codice o se valuta 1 e 2 su true con lo stesso numero di istruzioni per un particolare set di istruzioni, la velocità di esecuzione sarà la stessa.

In casi reali sarà sempre ugualmente veloce, ma sarebbe possibile immaginare un particolare compilatore e un particolare sistema quando questo sarebbe valutato diversamente.

Voglio dire: questa non è una domanda relativa al linguaggio (C).




L'unica ragione per cui riesco a pensare perché while(2)sarebbe più lento è:

  1. Il codice ottimizza il ciclo su

    cmp eax, 2

  2. Quando si verifica la sottrazione stai essenzialmente sottraendo

    un. 00000000 - 00000010 cmp eax, 2

    invece di

    b. 00000000 - 00000001 cmp eax, 1

cmpimposta solo i flag e non imposta un risultato. Quindi sui bit meno significativi sappiamo se abbiamo bisogno di prendere in prestito o meno con b . Mentre con a devi eseguire due sottrazioni prima di ottenere un prestito.






Related