Exploring PLINQ (Parallel LINQ) for Parallel Processing

PLINQ (Parallel LINQ) is a parallelized implementation of LINQ (Language Integrated Query) that enables queries to execute in parallel, taking advantage of multi-core processors to improve performance.

Key Features of PLINQ

  • Automatic Parallelization: PLINQ divides the data source into partitions and processes them on multiple threads automatically.
  • Declarative Syntax: The syntax remains similar to LINQ, making it easier to use for developers familiar with LINQ.
  • Scalability: PLINQ leverages all available processors for improved performance on large datasets.
  • Customizable Execution: You can control the degree of parallelism and execution behavior.

Basic Example: Parallelizing a Query

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        var numbers = Enumerable.Range(1, 100);

        // Parallel LINQ query
        var evenNumbers = numbers
            .AsParallel()
            .Where(n => n % 2 == 0)
            .ToList();

        Console.WriteLine("Even numbers:");
        evenNumbers.ForEach(Console.WriteLine);
    }
}

Example: Measuring Performance

using System;
using System.Linq;
using System.Diagnostics;

class Program
{
    static void Main()
    {
        var numbers = Enumerable.Range(1, 10_000_000).ToArray();
        var stopwatch = new Stopwatch();

        // Sequential processing
        stopwatch.Start();
        var sequentialSum = numbers.Where(n => n % 2 == 0).Sum();
        stopwatch.Stop();
        Console.WriteLine($"Sequential Sum: {sequentialSum}, Time: {stopwatch.ElapsedMilliseconds}ms");

        // Parallel processing
        stopwatch.Restart();
        var parallelSum = numbers.AsParallel().Where(n => n % 2 == 0).Sum();
        stopwatch.Stop();
        Console.WriteLine($"Parallel Sum: {parallelSum}, Time: {stopwatch.ElapsedMilliseconds}ms");
    }
}

Controlling Degree of Parallelism

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        var numbers = Enumerable.Range(1, 100);

        var results = numbers
            .AsParallel()
            .WithDegreeOfParallelism(2) // Use 2 processors
            .Where(n => n % 2 == 0)
            .ToList();

        results.ForEach(Console.WriteLine);
    }
}

Handling Exceptions in PLINQ

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        var numbers = new[] { 1, 2, 3, 0, 5 };

        try
        {
            var results = numbers.AsParallel()
                                 .Select(n => 100 / n)
                                 .ToList();
        }
        catch (AggregateException ex)
        {
            foreach (var innerException in ex.InnerExceptions)
            {
                Console.WriteLine(innerException.Message);
            }
        }
    }
}

Preserving Order with PLINQ

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        var numbers = Enumerable.Range(1, 10);

        var orderedResults = numbers
            .AsParallel()
            .AsOrdered()
            .Where(n => n % 2 == 0)
            .ToList();

        Console.WriteLine("Ordered Results:");
        orderedResults.ForEach(Console.WriteLine);
    }
}

When to Use PLINQ?

  • Computationally Intensive Tasks: PLINQ is suitable for tasks like image processing, mathematical computations, or large dataset analysis.
  • Large Datasets: It works best when processing large collections that can benefit from parallel execution.
  • Multi-Core Systems: PLINQ leverages the available CPU cores for parallel execution.

Limitations of PLINQ

  • For small datasets or simple queries, the overhead of parallelization may outweigh the benefits.
  • Avoid using PLINQ when queries modify shared state, as this can lead to race conditions.
  • PLINQ runs on multiple threads, so ensure thread safety in operations.

Best Practices

  • Measure performance using tools like Stopwatch to ensure PLINQ benefits your use case.
  • Use AsOrdered only when necessary, as it introduces additional overhead.
  • Handle exceptions using AggregateException.

PLINQ is a powerful tool for parallel processing, offering significant performance improvements when used correctly. It simplifies writing parallel code without needing to manage threads explicitly.

Up Next
    Ebook Download
    View all
    Learn
    View all