He escrito un pequeño programa de prueba y me sorprendió por qué la solución lock {}
funciona más rápido que sin bloqueo pero con el atributo [ThreadStatic]
sobre la variable estática..NET: ThreadStatic vs lock {}. ¿Por qué ThreadStaticAttribute degrada el rendimiento?
[ThreadStatic] fragmento:
[ThreadStatic]
private static long ms_Acc;
public static void RunTest()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int one = 1;
for (int i = 0; i < 100 * 1000 * 1000; ++i) {
ms_Acc += one;
ms_Acc /= one;
}
stopwatch.Stop();
Console.WriteLine("Time taken: {0}", stopwatch.Elapsed.TotalSeconds);
}
bloqueo {} fragmento:
private static long ms_Acc;
private static object ms_Lock = new object();
public static void RunTest()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int one = 1;
for (int i = 0; i < 100 * 1000 * 1000; ++i) {
lock (ms_Lock) {
ms_Acc += one;
ms_Acc /= one;
}
}
stopwatch.Stop();
Console.WriteLine("Time taken: {0}", stopwatch.Elapsed.TotalSeconds);
}
En mi máquina primer fragmento toma 4,2 segundos; segundo - 3.2 segundos, que es 1 segundo más rápido. Sin ThreadStatic y bloqueo: 1,2 segundos.
Tengo curiosidad por qué el atributo [ThreadStatic]
en este sencillo ejemplo agrega tantos al tiempo de ejecución del programa?
ACTUALIZACIÓN: Lo siento mucho, pero estos resultados son para DEBUG
compilación. Para RELEASE
, obtuve números completamente diferentes: (1.2; 2.4; 1.2). Para DEBUG
los números fueron (4.2; 3.2; 1.2).
Por lo tanto, para RELEASE
construir no parece haber [ThreadStatic]
de rendimiento de la pena de rendimiento.
Eso no es lo que veo en mi QuadCore. Si compilo Release on Any Cpu obtengo 0.81s para el primer fragmento y 4.5s para el segundo.El caso trivial sin seguridad de hilo toma 0.46s. – FuleSnabel
Tienes razón. Cambié del modo 'Debug' al' Release' y obtuve resultados similares a los tuyos. – Roman
Puede ayudar leer el código desmontado para comprender por qué obtiene resultados sorprendentes. – FuleSnabel