Condividi tramite


Procedura: scrivere una funzione di aggregazione PLINQ personalizzata

In questo esempio viene illustrato come utilizzare il metodo Aggregate per applicare una funzione di aggregazione personalizzata a una sequenza di origine.

Nota di avvisoAttenzione

Lo scopo di questo esempio è dimostrare l'utilizzo e potrebbe non essere eseguito più velocemente dell'equivalente query LINQ to Objects sequenziale.Per ulteriori informazioni sull'aumento di velocità, vedere Informazioni sull'aumento di velocità in PLINQ.

Esempio

Nell'esempio seguente viene calcolata la deviazione standard di una sequenza di interi.

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

        }
    }
}

In questo esempio viene utilizzato un overload dell'operatore di query standard Aggregate univoco in PLINQ. Questo overload accetta un oggetto System.Func<T1, T2, TResult> aggiuntivo come terzo parametro di input. Questo delegato combina i risultati di tutti i thread prima di eseguire il calcolo finale sui risultati aggregati. In questo esempio si sommano le somme di tutti i thread.

Notare che quando un corpo di espressioni lambda è formato da un'unica espressione, il valore restituito del delegato di System.Func<T, TResult> è il valore dell'espressione.

Vedere anche

Riferimenti

ParallelEnumerable

Concetti

Parallel LINQ (PLINQ)

Cronologia delle modifiche

Data

Cronologia

Motivo

Maggio 2010

Aggiunta nota sull'utilizzo rispetto all'aumento di velocità.

Commenti e suggerimenti dei clienti.