Cara: Mempercepat Isi Perulangan Kecil
Ketika perulangan Parallel.For memiliki tubuh kecil, perulangan mungkin berkinerja lebih lambat daripada perulangan berurutan yang setara, seperti untuk perulangan di C# dan untuk perulangan di Visual Basic. Kinerja yang lebih lambat disebabkan oleh overhead yang terlibat dalam partisi data dan biaya untuk memanggil delegasi pada setiap loop. Untuk mengatasi skenario tersebut, kelas Partitioner menyediakan metodePartitioner.Create, yang memungkinkan Anda untuk memberikan perulangan berurutan untuk isi delegasi, sehingga delegasi hanya dipanggil sekali per partisi, bukan sekali per iterasi. Untuk informasi selengkapnya, lihat Partisi Kustom untuk PLINQ dan TPL.
Contoh
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
Pendekatan yang ditunjukkan dalam contoh ini berguna ketika perulangan melakukan pekerjaan dalam jumlah kecil. Karena pekerjaan menjadi lebih mahal secara komputasi, Anda mungkin akan mendapatkan performa yang sama atau lebih baik dengan menggunakan perulangan For atau ForEach dengan partisi default tersebut.
Lihat juga
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk