Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

O Parallel.ForEach é mais rápido que o Parallel.For ?

Executei na minha máquina algumas repetidas vezes, e o paralle.foreach sempre executou mais rápido que o parallel.for. Minha máquina provavelmente tem um poder de processamento menor que a máquina do Marcelo, pois executa com mais tempo. Isso influencia em qual algoritmo irá performar melhor?

3 respostas
solução!

Oi Alex, tudo bem? Há quanto tempo, hein! :-D

Fiz umas alterações aqui na minha máquina de desenvolvimento (diferente da máquina onde eu gravo o curso), e rodando 20 vezes das duas formas, e aqui estão os resultados.

  • Parallel.For: foi mais rápido em 3 rodadas
  • Parallel.ForEach: foi mais rápido em 17 rodadas
Parallel.For: Tempo decorrido: 2,674 segundos
Parallel.ForEach: Tempo decorrido: 2,037 segundos

Parallel.For: Tempo decorrido: 2,011 segundos
Parallel.ForEach: Tempo decorrido: 2,113 segundos

Parallel.For: Tempo decorrido: 2,513 segundos
Parallel.ForEach: Tempo decorrido: 1,713 segundos

Parallel.For: Tempo decorrido: 2,514 segundos
Parallel.ForEach: Tempo decorrido: 2,122 segundos

.
.
.

Porém, descobri que ao converter a coleção itens para List, o método Parallel.Foreach() às vezes fica mais lento que o Parallel.For():

var itens = Enumerable.Range(0, 100).ToList();
  • Parallel.For: foi mais rápido em 14 rodadas
  • Parallel.ForEach: foi mais rápido em 6 rodadas
Parallel.For: Tempo decorrido: 2,687 segundos
Parallel.ForEach: Tempo decorrido: 2,522 segundos

Parallel.For: Tempo decorrido: 2,013 segundos
Parallel.ForEach: Tempo decorrido: 2,01 segundos

Parallel.For: Tempo decorrido: 2,513 segundos
Parallel.ForEach: Tempo decorrido: 2,514 segundos

Parallel.For: Tempo decorrido: 2,012 segundos
Parallel.ForEach: Tempo decorrido: 2,014 segundos

.
.
.

O que eu percebi é que a variável itens original estava sendo instanciada como um objeto RangeIterator, porém após a modificação ela passa a armazenar um System.Collections.Generic.List. Pelo visto, o método Foreach() é mais eficiente sobre o RangeIterator do que sobre o List. Então a lição aqui é evitar usar o método .ToList() em coleções IEnumerable, a não ser que seja realmente necessário, caso contrário isso pode provocar perdas de desempenho significativas.

Abraços e boa sorte com a certificação! marcelo

E ai Marcelo! Faz tempo mesmo..hehehe =D

O que vc falou sobre o ForEach() faz sentido. Olhando no código fonte do .NET, o metodo trata de forma diferente quando é um Enumerable ou quando é um List

Se quiser ver, segue o link Parallel.ForEach

Abraços!

E ai Marcelo! Faz tempo mesmo..hehehe =D

Rapaz, que mundo pequeno! hahaha

O que vc falou sobre o ForEach() faz sentido. Olhando no código fonte do .NET, o metodo trata de forma diferente quando é um Enumerable ou quando é um List

Se quiser ver, segue o link Parallel.ForEach

Abraços!

Exatamente, Alex! Eu tinha visto no código do GitHub do .NET Core que a estratégia para coleção IList<T> é diferente de IEnumerable<T>, e isso faz toda a diferença.

Um abraço e boa sorte com a certificação! Pra qualquer dúvida estamos aí!