Perfil de rendimiento en .NET

Escribí una clase que usaStopwatch para perfilar métodos yfor/foreach bucles Confor yforeach bucles prueba un bucle estándar contra unaParallel.For oParallel.ForEach implementación.

Escribirías pruebas de rendimiento así:

Método:

PerformanceResult result = Profiler.Execute(() => { FooBar(); });

En bucle:

SerialParallelPerformanceResult result = Profiler.For(0, 100, x => { FooBar(x); });

ForEach loop:

SerialParallelPerformanceResult result = Profiler.ForEach(list, item => { FooBar(item); });

Cada vez que hago las pruebas (una de.Execute, .For o.ForEach) Los puse en un bucle para ver cómo cambia el rendimiento con el tiempo.

Ejemplo de rendimiento podría ser:

Método de ejecución 1 = 200ms
Método de ejecución 2 = 12ms
Método de ejecución 3 = 0ms

Para ejecución 1 = 300ms (Serial), 100ms (Paralelo)
Para ejecución 2 = 20ms (Serie), 75ms (Paralelo)
Para ejecución 3 = 2ms (Serie), 50ms (Paralelo)

Ejecución de ForEach 1 = 350 ms (serie), 300 ms (paralelo)
Ejecución de ForEach 2 = 24 ms (serie), 89 ms (paralelo)
Ejecución de ForEach 3 = 1 ms (Serie), 21 ms (Paralelo)

Mis preguntas son:

¿Por qué el rendimiento cambia con el tiempo? ¿Qué hace .NET en segundo plano para facilitar esto?

¿Cómo / por qué una operación en serie es más rápida que una paralela? Me he asegurado de que hago las operaciones complejas para ver la diferencia correctamente ... ¡en la mayoría de los casos las operaciones en serie parecen más rápidas?

NOTA: Para el procesamiento paralelo estoy probando en una máquina de 8 núcleos.