web-dev-qa-db-fra.com

C # Filet rapide rapide (est) compteur

Comment obtenir un compteur thread safe en C # avec les meilleures performances possibles?

C'est aussi simple que cela:

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

Mais existe-t-il des alternatives plus rapides?

119
JohnDoDo

Ce serait plus simple:

return Interlocked.Increment(ref COUNTER);

MSDN Interlocked.Increment

214
Austin Salonen

Comme recommandé par d'autres, le Interlocked.Increment Aura de meilleures performances que lock(). Il suffit de jeter un coup d'œil à IL et à Assembly où vous verrez que Increment se transforme en une instruction "lock lock" et que sa variable est directement incrémentée (x86) ou "ajoutée" à (x64).

Cette instruction "verrouillage du bus" verrouille le bus pour empêcher une autre CPU d'accéder au bus pendant que la CPU appelante effectue son opération. Maintenant, jetez un coup d'œil à l'IL de l'instruction C # lock(). Ici, vous verrez les appels à Monitor afin de commencer ou de terminer une section.

En d’autres termes, l’instruction .Net lock() fait beaucoup plus que l’instrument .Net Interlocked.Increment.

SO, si tout ce que vous voulez faire est d’incrémenter une variable, Interlock.Increment Sera plus rapide. Passez en revue toutes les méthodes inter-verrouillées pour voir les différentes opérations atomiques disponibles et trouver celles qui répondent à vos besoins. Utilisez lock() lorsque vous souhaitez effectuer des tâches plus complexes, telles que plusieurs incréments/décréments interdépendants, ou pour sérialiser l'accès à des ressources plus complexes que des entiers.

102
Les

Je vous suggère d’utiliser l’incrémentation interlock intégrée de .NET dans la bibliothèque System.Threading.

Le code suivant incrémente une variable longue par référence et est totalement thread-safe:

Interlocked.Increment(ref myNum);

Source: http://msdn.Microsoft.com/en-us/library/dd78zt0c.aspx

26
Andrew White
15
fsimonazzi