Perfil de desempenho no .NET

Eu escrevi uma aula que usaStopwatch para perfis de métodos efor/foreach rotações. Comfor eforeach loops testa um loop padrão contra umParallel.For ouParallel.ForEach implementação.

Você escreveria testes de desempenho assim:

Método:

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

Para loop:

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

ForEach loop:

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

Sempre que executo os testes (um dos.Execute, .For ou.ForEachEu os coloco em um loop para que eu possa ver como o desempenho muda com o tempo.

Exemplo de desempenho pode ser:

Execução do método 1 = 200ms
Execução do método 2 = 12ms
Execução do método 3 = 0ms

Para execução 1 = 300ms (Serial), 100ms (Paralela)
Para execução 2 = 20ms (Serial), 75ms (Paralela)
Para execução 3 = 2ms (Serial), 50ms (Paralela)

Para cada execução 1 = 350ms (Serial), 300ms (Paralela)
Para cada execução 2 = 24ms (Serial), 89ms (Paralela)
Para cada execução 3 = 1ms (Serial), 21ms (Paralela)

Minhas perguntas são:

Por que o desempenho muda com o tempo, o que o .NET está fazendo em segundo plano para facilitar isso?

Como / porque é uma operação serial mais rápida que uma paralela? Eu me certifiquei de tornar as operações complexas para ver a diferença corretamente ... na maioria dos casos, as operações em série parecem mais rápidas!

NOTA: Para processamento paralelo, estou testando em uma máquina de 8 núcleos.