Partager via


Comment : écrire une fonction d'agrégation PLINQ personnalisée

Cet exemple indique comment utiliser la méthode Aggregate pour appliquer une fonction d'agrégation personnalisée à une séquence source.

Remarque AttentionAttention

Cet exemple est destiné à montrer l'utilisation et peut ne pas s'exécuter plus rapidement que la requête LINQ to Objects séquentielle équivalente.Pour plus d'informations sur l'accélération, consultez Fonctionnement de l'accélération dans PLINQ.

Exemple

L'exemple suivant calcule l'écart type d'une séquence d'entiers.

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();

        }
    }
}

Cet exemple utilise une surcharge de l'opérateur de requête standard d'agrégation qui est unique à PLINQ. Cette surcharge prend un System.Func<T1, T2, TResult> supplémentaire comme troisième paramètre d'entrée. Ce délégué combine les résultats de tous les threads avant d'exécuter le dernier calcul sur les résultats groupés. Dans cet exemple, nous ajoutons les sommes de tous les threads.

Notez que lorsqu'un corps d'expression lambda se compose d'une expression unique, la valeur de retour du délégué System.Func<T, TResult> est la valeur de l'expression.

Voir aussi

Référence

ParallelEnumerable

Concepts

Parallel LINQ (PLINQ)

Historique des modifications

Date

Historique

Motif

Mai 2010

Remarque ajoutée concernant l'utilisation et l'accélération.

Commentaires client.