Imagine that you have a directory on your computer with 8 FLAC music files. Great format on purpose, clean audio.
Now imagine that you want to convert these files from FLAC to MP3 (not so good) because your cd-player (nor 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 invented now.
FlacAudio[] audioFiles = FlacHelper.ReadFromDirectory("caminhoDoDiretorio");
Ready, 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 why wait?
Let's rewrite code so that all processing power is enjoyed:
List<Mp3Audio> mp3Files = new List<Mp3Audio>();
Parallel.ForEach(audioFiles, file =>
{
Mp3Audio mp3 = FlacHelper.ConvertToMp3(file);
mp3Files.Add(mp3);
});
Now, in this code, the foreach
of Parallel
discovers and uses all the available threads of your processor so that the action, which in the case is to convert audio files, is executed in parallel, then each thread will convert a file at the same time.
Considering that it would take 1 minute for each file, the default%% would take a total of 8 minutes, whereas a foreach
would take 1 minute considering 8 files in the directory and a processor with 8 threads.
Parallel.ForEach
works just as you imagine it:
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 are CPU-dependent and can be run in parallel when there is more than one occurrence of the item being processed, similarly to our list of songs.
Leave it :
Using Parallel.For
in simple operations / iterations that do not use many resources is not guaranteed to be faster than a% default%. In fact, the cost of allocating threads in the way that Parallel.ForEach
does can cause an overhead to let its code slow down, so the "weight" of the operation to be executed within foreach
is what it will dictate if it compensates or not the use of the parallel form.