方法: カスタムの PLINQ 集約関数を記述する

更新 : 2010 年 5 月

この例では、Aggregate メソッドを使用してカスタムの集計関数をソース シーケンスに適用する方法を示します。

Caution メモ注意

この例は使用法を示すことを目的としており、同等の LINQ to Objects 順次クエリよりも実行速度が遅い場合があります。高速化の詳細については、「PLINQ での高速化について」を参照してください。

使用例

次の例では、整数のシーケンスの標準偏差を計算します。

Class aggregation
    Private Shared Sub Main(ByVal args As String())

        ' Create a data source for demonstration purposes.
        Dim source As Integer() = New Integer(99999) {}
        Dim rand As New Random()
        For x As Integer = 0 To source.Length - 1
            ' Should result in a mean of approximately 15.0.
            source(x) = rand.[Next](10, 20)
        Next

        ' Standard deviation calculation requires that we first
        ' calculate the mean average. Average is a predefined
        ' aggregation operator, along with Max, Min and Count.
        Dim mean As Double = source.AsParallel().Average()


        ' We use the overload that is unique to ParallelEnumerable. The 
        ' third Func parameter combines the results from each thread.
        ' initialize subtotal. Use decimal point to tell 
        ' the compiler this is a type double. Can also use: 0d.

        ' do this on each thread

        ' aggregate results after all threads are done.

        ' perform standard deviation calc on the aggregated result.
        Dim standardDev As Double = source.AsParallel().Aggregate(0.0R, Function(subtotal, item) subtotal + Math.Pow((item - mean), 2), Function(total, thisThread) total + thisThread, Function(finalSum) Math.Sqrt((finalSum / (source.Length - 1))))
        Console.WriteLine("Mean value is = {0}", mean)
        Console.WriteLine("Standard deviation is {0}", standardDev)

        Console.ReadLine()
    End Sub
End Class
namespace PLINQAggregation
{
    using System;
    using System.Linq;

    class aggregation
    {
        static void Main(string[] args)
        {

            // Create a data source for demonstration purposes.
            int[] source = new int[100000];
            Random rand = new Random();
            for (int x = 0; x < source.Length; x++)
            {
                // Should result in a mean of approximately 15.0.
                source[x] = rand.Next(10, 20);
            }

            // Standard deviation calculation requires that we first
            // calculate the mean average. Average is a predefined
            // aggregation operator, along with Max, Min and Count.
            double mean = source.AsParallel().Average();


            // We use the overload that is unique to ParallelEnumerable. The 
            // third Func parameter combines the results from each thread.
            double standardDev = source.AsParallel().Aggregate(
                // initialize subtotal. Use decimal point to tell 
                // the compiler this is a type double. Can also use: 0d.
                0.0,

                // do this on each thread
                 (subtotal, item) => subtotal + Math.Pow((item - mean), 2),

                 // aggregate results after all threads are done.
                 (total, thisThread) => total + thisThread,

                // perform standard deviation calc on the aggregated result.
                (finalSum) => Math.Sqrt((finalSum / (source.Length - 1)))
            );
            Console.WriteLine("Mean value is = {0}", mean);
            Console.WriteLine("Standard deviation is {0}", standardDev);
            Console.ReadLine();

        }
    }
}

この例では、PLINQ に固有の Aggregate 標準クエリ演算子のオーバーロードを使用します。 このオーバーロードでは、3 つ目の入力パラメーターとして System.Func<T1, T2, TResult> を使用します。 このデリゲートでは、すべてのスレッドの結果をまとめてから、集計結果での最終的な計算が実行されます。 この例では、すべてのスレッドからの合計が追加されます。

ラムダ式の本体が単一の式から構成される場合、System.Func<T, TResult> デリゲートの戻り値は式の値になります。

参照

参照

ParallelEnumerable

概念

Parallel LINQ (PLINQ)

履歴の変更

日付

履歴

理由

2010 年 5 月

使用法と高速化に関する説明を 追加。

カスタマー フィードバック