Lingua
Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Quando un Parallel.For ciclo ha un corpo piccolo, può essere eseguito più lentamente rispetto al ciclo sequenziale equivalente, ad esempio il ciclo for in C# e il ciclo For in Visual Basic. Le prestazioni più lente sono causate dal sovraccarico dovuto al partizionamento dei dati e al costo di richiamare un delegato in ogni iterazione del ciclo. Per risolvere questi scenari, la Partitioner classe fornisce il Partitioner.Create metodo , che consente di fornire un ciclo sequenziale per il corpo del delegato, in modo che il delegato venga richiamato una sola volta per partizione, anziché una volta per iterazione. Per ulteriori informazioni, vedere partizionatori personalizzati per PLINQ e TPL.
Example
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main()
{
// Source must be array or IList.
var source = Enumerable.Range(0, 100000).ToArray();
// Partition the entire source array.
var rangePartitioner = Partitioner.Create(0, source.Length);
double[] results = new double[source.Length];
// Loop over the partitions in parallel.
Parallel.ForEach(rangePartitioner, (range, loopState) =>
{
// Loop over each range element without a delegate invocation.
for (int i = range.Item1; i < range.Item2; i++)
{
results[i] = source[i] * Math.PI;
}
});
Console.WriteLine("Operation complete. Print results? y/n");
char input = Console.ReadKey().KeyChar;
if (input == 'y' || input == 'Y')
{
foreach(double d in results)
{
Console.Write("{0} ", d);
}
}
}
}
Imports System.Threading.Tasks
Imports System.Collections.Concurrent
Module PartitionDemo
Sub Main()
' Source must be array or IList.
Dim source = Enumerable.Range(0, 100000).ToArray()
' Partition the entire source array.
' Let the partitioner size the ranges.
Dim rangePartitioner = Partitioner.Create(0, source.Length)
Dim results(source.Length - 1) As Double
' Loop over the partitions in parallel. The Sub is invoked
' once per partition.
Parallel.ForEach(rangePartitioner, Sub(range, loopState)
' Loop over each range element without a delegate invocation.
For i As Integer = range.Item1 To range.Item2 - 1
results(i) = source(i) * Math.PI
Next
End Sub)
Console.WriteLine("Operation complete. Print results? y/n")
Dim input As Char = Console.ReadKey().KeyChar
If input = "y"c Or input = "Y"c Then
For Each d As Double In results
Console.Write("{0} ", d)
Next
End If
End Sub
End Module
L'approccio illustrato in questo esempio è utile quando il ciclo esegue una quantità minima di lavoro. Man mano che il lavoro diventa più oneroso dal punto di vista computazionale, è probabile che si ottengano le stesse prestazioni o migliori usando un ciclo For o ForEach con il partitioner predefinito.