2012-11-01 4 views
78

Qual è il modo per ottenere un contatore thread-safe in C# con le migliori prestazioni possibili?C# contatore veloce sicuro (est)

Questo è così semplice come si arriva:

public static long GetNextValue() 
{ 
    long result; 
    lock (LOCK) 
    { 
     result = COUNTER++; 
    } 
    return result; 
} 

ma ci sono alternative più veloci?

risposta

20

vi suggerisco di utilizzare .NET di costruito in incremento di blocco nella biblioteca System.Threading.

Il seguente codice incrementare molto variabile per riferimento ed è completamente thread-safe:

Interlocked.Increment(ref myNum); 

Fonte: http://msdn.microsoft.com/en-us/library/dd78zt0c.aspx

66

Come raccomandato da altri, la Interlocked.Increment avrà prestazioni migliori rispetto lock(). Basta dare un'occhiata all'IL e al Assembly dove vedrai che Increment diventa un'istruzione "bus lock" e la sua variabile viene incrementata direttamente (x86) o "aggiunta" a (x64).

Questa istruzione "lock lock" blocca il bus per impedire ad un'altra CPU di accedere al bus mentre la CPU chiamante esegue la sua operazione. Ora, date un'occhiata all'IL di C# lock(). Qui vedrai le chiamate allo Monitor per iniziare o terminare una sezione.

In altre parole, l'istruzione .Net lock() sta facendo molto più di .Net Interlocked.Increment.

SO, se tutto ciò che si vuole fare è incrementare una variabile, Interlock.Increment sarà più veloce. Rivedi tutti i metodi Interlocked per vedere le varie operazioni atomiche disponibili e trovare quelle che si adattano alle tue esigenze. Utilizzare lock() quando si desidera eseguire operazioni più complesse come incrementi/decrementi multipli correlati o serializzare l'accesso a risorse più complesse degli interi.

+0

Voto superiore per l'aggiunta del contesto – fsimonazzi

+0

-1 per dettagli di implementazione. È vero che il blocco è molto più lento di un'operazione atomica, ma questo non ha nulla a che fare con l'IL. Quelle chiamate di funzione sarebbero molto più veloci di un'operazione atomica se non per la loro semantica, che non è intrinsecamente richiesta dall'IL. – Puppy