Usando il prefisso cicli incrementati in C #

4

Quando ho iniziato a programmare al college, un amico mi ha incoraggiato ad usare l'operatore di incremento del prefisso ++i invece del suffisso i++ , adducendo che c'era una leggera possibilità di prestazioni migliori senza una reale possibilità di svantaggio. Mi rendo conto che questo è vero in C ++, ed è diventata un'abitudine generale che continuo a fare.

Sono portato a credere che faccia poca o nessuna differenza quando viene usato in un ciclo in C #, indipendentemente dal tipo di dati. Apparentemente l'operatore ++ non può essere sovrascritto. Tuttavia, mi piace l'aspetto di più, e non vedo un rovescio della medaglia.

Tuttavia, ha stupito un collega solo un momento fa, ha fatto l'ipotesi (abbastanza logica) che il mio ciclo si sarebbe interrotto presto come risultato. È un programmatore autodidatta e apparentemente non ha mai incontrato la convenzione C ++. Questo mi ha fatto dubitare se il comportamento equivalente degli operatori di incremento e decremento pre- e post-fix nei loop fosse abbastanza noto.

È accettabile continuare a utilizzare ++i nei costrutti di loop a causa delle preferenze di stile, anche se non presenta alcun reale vantaggio in termini di prestazioni? O è probabile che causi confusione tra altri programmatori?

  • Nota: si presume che la convenzione ++i sia utilizzata in modo coerente in tutto il codice.
posta KChaloux 11.09.2012 - 21:56
fonte

6 risposte

11

Penso che dovresti rispettare le convenzioni a cui sono abituati i tuoi colleghi di lavoro. Il principio di sorpresa minima. Non vuoi sederti e capire perché una semplice operazione è scritta in un modo insolito senza motivo, quindi perché dovrebbe il prossimo ragazzo che sta leggendo il tuo codice?

    
risposta data 11.09.2012 - 22:00
fonte
6

Non ottimizzato, i++ fa una copia, quindi j = i++ si traduce in:

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

Mentre j = ++i si traduce in:

i = i + 1;
j = i;

Quella copia in più in una variabile temporanea è ciò che causa il successo della prestazione teorica con il post-incremento. Tuttavia, poiché il nuovo valore di i non dipende da j , può essere ottimizzato per:

j = i;
i = i + 1;

Che, salvo eventuali stranezze della pipeline, ha esattamente lo stesso runtime della versione pre-incremento. Risulta che ci sono pochissime circostanze del mondo reale in cui un'analoga ottimizzazione del compilatore non è possibile, quindi c'è praticamente zero ragioni per scegliere il pre-incremento per ragioni di ottimizzazione. Gli incrementi autonomi, come in un ciclo for , sono ancora più facili da ottimizzare fino alla stessa istruzione.

In altre parole, seguire la convenzione di codifica a meno che non sia sintatticamente significativa. Ma non fa male educare i tuoi colleghi o se l'unica ragione per cui non la usano è basata su una comprensione errata di come funzionano for loops.

    
risposta data 11.09.2012 - 22:50
fonte
3

++i e i++ sono operazioni diverse.

Verifica questo link dà un esempio migliore di quello che ho avuto. ma ero sulla strada giusta.

int i = 1;

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



i = 1; // <-- reset i

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

È buona norma utilizzare la convenzione di codifica su cui i membri del tuo team / università sono d'accordo. Non importa davvero come hai deciso di fare che per quanto funziona e che è stato implementato in modo incostante. Mantenere il codice semplice e pulito (principio KISS) dovrebbe essere l'obiettivo principale.

È molto più importante avere uno stile coerente di codifica nei grandi progetti per facilitare la manutenzione nelle fasi successive.

Ecco un link alle linee guida MS - Convenzioni di codifica C # (Guida alla programmazione C #)

    
risposta data 11.09.2012 - 22:07
fonte
1

Direi che dipende esattamente da cosa intendi per "preferenza di stile". Se intendi che vuoi utilizzare "++ i" ovunque compresi come for(i=0; i<x; ++i) , allora va bene. Se invece vuoi usarlo in modo specifico in loop mentre altrove usando i++ o i+=1 (o viceversa) allora questa è una pessima idea, dovresti essere coerente attraverso il programma.

Finché sei coerente e non lo stai usando in un'espressione di confronto o più volte in una chiamata di metodo, questo non dovrebbe essere una sorpresa per nessuno. In particolare il ciclo for è

  1. Assegnazione
  2. di confronto
  3. Corpo, se, vero e infine
  4. Incremento

Finché non stai facendo il tuo incremento in 1, 2 o 3, non ci dovrebbero essere sorprese.

D'altra parte, se a volte usi post incremento e talvolta pre-incremento, o lo fai in modo non standard f(i++, ++i); , allora lascerai qualcuno a fare una pausa e potresti commettere un errore te stesso o conduci qualcun altro a commettere un errore.

Nota che se scegli ++ io, ti consiglio di non farlo mai if(++i<x) ...

    
risposta data 12.09.2012 - 04:07
fonte
0

È vero che i++ e ++i sono operazioni diverse. Hanno lo stesso effetto collaterale (modificando il valore memorizzato di i ), ma producono valori diversi e come risposta Karl Bielefeldt indica un'implementazione non ottimizzata di i++ potrebbe dover memorizzare il valore precedente di i in un temporaneo.

Ma se li stai utilizzando in un contesto in cui il risultato non viene utilizzato, non dovrebbe esserci alcuna differenza.

Ad esempio, in uno stile C per il ciclo, la terza espressione nell'intestazione del ciclo viene valutata solo per i suoi effetti collaterali; ogni valore che produce viene quietamente scartato. Questi due cicli:

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

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

hanno una semantica identica, e se il tuo compilatore non genera codice identico, o almeno equivalente per entrambi, dovresti probabilmente trovare un compilatore migliore.

Quindi in questo contesto, la scelta tra i ++ e ++ i dovrebbe essere puramente di stile. Se hai uno standard di codifica, seguilo. Se non lo fai, sii coerente.

Se stai utilizzando i ++ o ++ i in un contesto in cui il risultato è usato, allora le prestazioni non saranno un fattore; usa quello che ti dà la risposta che ti serve. Oppure considera se il tuo codice potrebbe essere più pulito se lo riorganizzi in modo da non utilizzare il risultato di i ++ o ++ i .

    
risposta data 29.09.2012 - 01:24
fonte

Leggi altre domande sui tag