Compartilhar via


Como: Escrever uma função agregada de PLINQ personalizado

Este exemplo mostra como usar o Aggregate método para aplicar uma função de agregação personalizada para uma seqüência de origem.

Observação de cuidadoCuidado

Este exemplo destina-se para demonstrar o uso e pode não ser executado mais rápido do que o equivalente LINQ to Objects seqüencial de consulta de.Para obter mais informações sobre o aumento de velocidade, consulte Aumento de velocidade de compreensão no PLINQ.

Exemplo

O exemplo a seguir calcula o desvio padrão de uma seqüência de números inteiros.

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

        }
    }
}

Este exemplo usa uma sobrecarga de operador de consulta padrão agregado que é exclusivo para PLINQ. Essa sobrecarga tem um extra System.Func<T1, T2, TResult> como o terceiro parâmetro de entrada. Este representante combina os resultados de todos os threads antes de executar o cálculo final nos resultados agregados. Neste exemplo podemos some as somas de todos os threads.

Observe que, quando o corpo de uma expressão lambda consiste em uma única expressão, o valor de retorno de System.Func<T, TResult> representante é o valor da expressão.

Consulte também

Referência

ParallelEnumerable

Conceitos

Parallel LINQ PLINQ)

Histórico de alterações

Date

History

Motivo

Maio de 2010

Observação adicionada referentes ao uso vs. aumento de velocidade.

Comentários do cliente.