C#中的並行處理、並行查詢的方法你用對了嗎?

架構師老盧發表於2023-12-05

Parallel.ForEach

Parallel.ForEach 是一個用於在集合上並行執行迭代操作的強大工具。它透過有效地利用多核處理器的能力來提高效能。Parallel.ForEach 不僅能夠簡化並行程式設計,而且它在執行簡單迴圈時可以提供比傳統迭代更好的效能。

下面是一個簡單的示例,演示瞭如何使用 Parallel.ForEach 並行處理一個整數列表:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
        List<int> numbers = GetNumbers();

        // 使用 Parallel.ForEach 並行處理整數列表
        Parallel.ForEach(numbers, num =>
        {
            int result = ProcessNumber(num);
            Console.WriteLine($"Processed {num} - Result: {result}");
        });

        Console.ReadLine();
    }

    static List<int> GetNumbers()
    {
        // 獲取一個包含大量整數的列表
        List<int> numbers = new List<int>();
        for (int i = 1; i <= 10000; i++)
        {
            numbers.Add(i);
        }
        return numbers;
    }

    static int ProcessNumber(int number)
    {
        // 模擬一些計算密集型的操作
        return number * number;
    }
}

在上面的例子中,Parallel.ForEach 會並行地處理 numbers 列表中的每個元素,並呼叫 ProcessNumber 方法。由於這個示例中的計算是相對簡單的,因此並行化可能在效能上並不明顯。實際上,Parallel.ForEach 對於處理更大規模的資料集或更復雜的計算任務時效果更為顯著。

AsParallel

AsParallel 是 LINQ 中的方法,它能夠將查詢操作並行化。使用 AsParallel 可以使 LINQ 查詢在多個處理器上並行執行,提高查詢效能。它返回一個 ParallelQuery<T> 物件,支援並行執行 LINQ 操作。

下面是一個示例,展示瞭如何使用 AsParallel 在整數列表上執行並行 LINQ 查詢:

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        List<int> numbers = GetNumbers();

        // 使用 AsParallel 在整數列表上執行並行 LINQ 查詢
        var result = numbers
            .AsParallel()
            .Where(num => num % 2 == 0)  // 過濾偶數
            .Select(num => num * num)     // 對偶數取平方
            .ToList();

        // 輸出結果
        Console.WriteLine("Parallel LINQ Result:");
        foreach (var num in result)
        {
            Console.WriteLine(num);
        }

        Console.ReadLine();
    }

    static List<int> GetNumbers()
    {
        // 獲取一個包含大量整數的列表
        List<int> numbers = new List<int>();
        for (int i = 1; i <= 10000; i++)
        {
            numbers.Add(i);
        }
        return numbers;
    }
}

在上面的例子中,AsParallel 被用於將 LINQ 查詢並行化。查詢首先過濾出列表中的偶數,然後計算每個偶數的平方。最終結果是一個包含平方值的列表。這裡的示例相對簡單,但在處理更大規模或更復雜的資料時,AsParallel 可以顯著提高效能。

區別與效能比較

區別:

  1. 用途不同:
  2. Parallel.ForEach 用於並行處理集合的元素,可以直接應用於迴圈迭代。
  3. AsParallel 用於將 LINQ 查詢並行化,主要用於在 LINQ 查詢中實現並行處理。
  4. 操作物件不同:
  5. Parallel.ForEach 操作集合的元素,需要提供一個委託來定義每個元素上的操作。
  6. AsParallel 操作 LINQ 查詢,使得查詢中的操作能夠在並行上執行。

效能比較:

效能的相對優劣取決於具體的使用場景和資料集。通常來說:

  • Parallel.ForEach 在直接的集合迭代操作中可能更為高效,特別是對於簡單的計算密集型任務。
  • AsParallel 更適合於在 LINQ 查詢中進行並行處理,特別是對於需要進行篩選、對映和其他複雜操作的情況。

在實際應用中,建議根據任務的性質選擇合適的工具。如果你有一個簡單的集合迭代任務,Parallel.ForEach 可能更合適。如果你在進行復雜的查詢操作,AsParallel 可能更適用。

在並行程式設計中,選擇使用 Parallel.ForEach 還是 AsParallel 取決於任務的性質。在處理集合元素時,Parallel.ForEach 提供了直觀且簡單的方式;而在進行復雜的 LINQ 查詢時,AsParallel 提供了更靈活的並行處理能力。在實際應用中,透過仔細分析任務需求和效能特徵,可以更好地選擇適當的工具來實現並行化。