Imagine you have a directory on your computer with 8 music files in FLAC format. Excellent format by the way, clean audio.
Now imagine that you want to convert these files from FLAC to MP3 (not so good) as your cd-player (not even mine) recognize the FLAC format. You will create your own code to convert audio files:
First, let’s get a list of the audios using a method I just invented.
FlacAudio[] audioFiles = FlacHelper.ReadFromDirectory("caminhoDoDiretorio");
Okay, we have a list of the 8 music files.
Now let’s convert them:
List<Mp3Audio> mp3Files = new List<Mp3Audio>();
foreach (FlacAudio file in audioFiles)
{
Mp3Audio mp3 = FlacHelper.ConvertToMp3(file);
mp3Files.Add(mp3);
}
// Salvar os arquivos convertidos no diretório destino...
Here, in this iterator foreach
only one thread is used for each of the 8 files, so while the first one is being converted, the other 7 are impatient waiting. But look, you have an Intel Core I7 processor with 8 threads available, so to wait?
We will rewrite code so that all this processing power is enjoyed:
List<Mp3Audio> mp3Files = new List<Mp3Audio>();
Parallel.ForEach(audioFiles, file =>
{
Mp3Audio mp3 = FlacHelper.ConvertToMp3(file);
mp3Files.Add(mp3);
});
Okay, in this code the foreach
of Parallel
discovers and utilizes all the available threads of your processor so that the action, which in this case is to convert audio files, runs in parallel, so each thread will convert a file at the same time.
Whereas it would take 1 minute for each file, the foreach
standard would take a total of 8 minutes while a Parallel.ForEach
it would take 1 minute considering 8 files in the directory and a processor with 8 threads.
The Parallel.For
works exactly as you imagine:
List<Mp3Audio> mp3Files = new List<Mp3Audio>();
Parallel.For(0, files.Length - 1,
index => {
Mp3Audio mp3 = FlacHelper.ConvertToMp3(audioFiles[index]);
mp3Files.Add(mp3);
}); // Index é o número da iteração atual, que neste caso parte de zero e é incrementada a cada iteração.
When to use:
For operations that depend on processing (CPU-Bound) and can be performed in parallel when there is more than one item occurrence to be processed, similarly to our playlist.
Caveat:
Use the Parallel.ForEach
in simple operations/iterations that do not use many features is no guarantee to be faster than a foreach
standard. Actually the cost of allocating threads in the way that the Parallel
can cause an "overhead" that slows down your code, then the "weight" of the operation to be executed within the foreach
is what will dictate whether or not to compensate for the use of the parallel form.
I think it’s already answered here: https://answall.com/q/211053/101
– Maniero
@Bigown, what I don’t understand is the use of Parellel. Your answer specifies the use of loops and even links the Parallel, but does not explain the subject or say when to use them.
– Marco Souza