Using PLINQ (Parallel Language In Query) in .NET 4.0
Parallel LINQ (PLINQ) is a parallel implementation of LINQ to Objects. It is located in System.Threading.Tasks.Parallel.
In many scenarios, PLINQ can significantly increase the speed of LINQ to Objects queries by using all available cores
on the host computer more efficiently.
I bring you my example, where I tested the speed of PLINQ, and the increase of speed was enormous!
PLINQ vs. ForEach loop comparison
A picture is worth a thousand words!
PLINQ - code bellow
ForEach loop - just a normal loop
PLINQ get the job done in 02.00 seconds(!), while ForEach loop processed images for 03.25 seconds.
Use Parallel Language Integrated Query (PLINQ) to take advantage of multi-processor computers
and the newer wave of multi-core processors.
PLINQ sample code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;
namespace MB.ParallelLanguageInQuery
{
class Program
{
static void Main(string[] args)
{
// ******************************************************************************************
// For demonstration purpose, I will use images located in Windows 7 default picture folder
// NOTE - I added some more images so that there is more "job" to do!
// ******************************************************************************************
// Get the names of all JPG files
string[] files = System.IO.Directory.GetFiles(@"C:\Users\Public\Pictures\Sample Pictures", "*.jpg");
// We create new subfolder called "Modified", where we will store modified images
string subDirectory_Modified = @"C:\Users\Public\Pictures\Sample Pictures\Modified";
System.IO.Directory.CreateDirectory(subDirectory_Modified);
// We will use Stopwatch class to determine how long it takes to perform the procedure
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
// ------------------------------------------------------------------------------------------
// PLINQ code - for each file do something...
// ------------------------------------------------------------------------------------------
Parallel.ForEach(files, currentFile =>
{
string filename = System.IO.Path.GetFileName(currentFile);
System.Drawing.Image image = System.Drawing.Image.FromFile(currentFile);
System.Drawing.Graphics graphic = Graphics.FromImage(image);
// ------------------------------------------------------------------------------------------
// NOTE - the more complex work you do here, the difference between PLINQ and
// sequential foreach loop will be greater
// ------------------------------------------------------------------------------------------
graphic.DrawString(filename, new Font("Arial", 15), new SolidBrush(Color.White), new PointF(50, 50));
graphic.DrawImage(image, 0, 0, 1000, 1000);
graphic.RotateTransform(180);
image.Save(System.IO.Path.Combine(subDirectory_Modified, filename));
// ------------------------------------------------------------------------------------------
Console.WriteLine("Processing {0} on thread {1}", filename, Thread.CurrentThread.ManagedThreadId);
});
stopwatch.Stop();
Console.WriteLine("\nProcessing complete in {0} seconds. Press any key to exit.", stopwatch.Elapsed);
Console.ReadKey();
}
}
}