Opsi Penggabungan di PLINQ
Saat kueri dijalankan secara paralel, PLINQ mempartisi rangkaian sumber sehingga beberapa utas dapat bekerja pada bagian yang berbeda secara bersamaan, biasanya pada utas terpisah. Jika hasilnya akan dikonsumsi pada satu utas, misalnya, dalam perulangan foreach
(For Each
dalam Visual Basic), maka hasil dari setiap utas harus digabungkan kembali menjadi satu rangkaian. Jenis penggabungan yang dilakukan PLINQ bergantung pada operator yang ada dalam kueri. Misalnya, operator yang memberlakukan urutan baru pada hasil harus menyangga semua elemen dari semua utas. Dari perspektif utas yang mengonsumsi (yang juga utas pengguna aplikasi) kueri yang sepenuhnya di-buffer mungkin berjalan untuk jangka waktu yang nyata sebelum menghasilkan hasil pertamanya. Operator lain, secara default, sebagian di-buffer; mereka menghasilkan hasil mereka secara berkelompok. Satu operator, ForAll tidak di-buffer secara default. Operator ini menghasilkan semua elemen dari semua utas dengan cepat.
Dengan menggunakan metode WithMergeOptions, seperti yang ditunjukkan dalam contoh berikut, Anda dapat memberikan petunjuk ke PLINQ yang menunjukkan jenis penggabungan apa yang akan dilakukan.
var scanLines = from n in nums.AsParallel()
.WithMergeOptions(ParallelMergeOptions.NotBuffered)
where n % 2 == 0
select ExpensiveFunc(n);
Dim scanlines = From n In nums.AsParallel().WithMergeOptions(ParallelMergeOptions.NotBuffered)
Where n Mod 2 = 0
Select ExpensiveFunc(n)
Untuk contoh lengkapnya, lihat Cara: Menentukan Opsi Penggabungan di PLINQ.
Jika kueri tertentu tidak dapat mendukung opsi yang diminta, maka opsi itu hanya akan diabaikan. Dalam kebanyakan kasus, Anda tidak perlu menentukan opsi penggabungan untuk kueri PLINQ. Namun, dalam beberapa kasus Anda mungkin menemukan dengan pengujian dan pengukuran yang terbaik dijalankan kueri dalam mode non-default. Penggunaan umum opsi ini adalah memaksa operator penggabungan-gugus untuk mengalirkan hasilnya untuk menyediakan antarmuka pengguna yang lebih responsif.
ParallelMergeOptions
Enumerasi ParallelMergeOptions mencakup opsi berikut yang menentukan, untuk bentuk kueri yang didukung, bagaimana output akhir kueri dihasilkan saat hasilnya dikonsumsi pada satu utas:
Not Buffered
Opsi NotBuffered ini menyebabkan setiap elemen yang diproses dikembalikan dari setiap utas segera setelah diproduksi. Perilaku ini analog dengan "pengaliran" output. Jika operator AsOrdered ada dalam kueri,
NotBuffered
mempertahankan urutan elemen sumber. MeskipunNotBuffered
mulai menghasilkan hasil segera setelah tersedia, total waktu untuk menghasilkan semua hasil mungkin masih lebih lama daripada menggunakan salah satu opsi penggabungan lainnya.Auto Buffered
Opsi AutoBuffered ini menyebabkan kueri untuk mengumpulkan elemen ke dalam buffer dan kemudian secara berkala menghasilkan konten buffer sekaligus ke utas yang mengonsumsi. Proses ini sama seperti menghasilkan data sumber dalam "gugus" alih-alih menggunakan perilaku "streaming" dari
NotBuffered
.AutoBuffered
mungkin perlu waktu lebih lama daripadaNotBuffered
untuk membuat elemen pertama tersedia pada utas yang mengonsumsi. Ukuran buffer dan perilaku menghasilkan yang tepat tidak dapat dikonfigurasi dan dapat bervariasi, tergantung pada berbagai faktor yang terkait dengan kueri.FullyBuffered
Opsi FullyBuffered ini menyebabkan output seluruh kueri di-buffer sebelum salah satu elemen tersebut dihasilkan. Ketika Anda menggunakan opsi ini, mungkin diperlukan waktu lebih lama sebelum elemen pertama tersedia pada utas yang mengonsumsi, tetapi hasil lengkapnya mungkin masih dihasilkan lebih cepat daripada menggunakan opsi lain.
Operator Kueri yang Mendukung Opsi Penggabungan
Tabel berikut mencantumkan operator yang mendukung semua mode opsi penggabungan, tunduk pada batasan yang ditentukan.
Operator | Batasan |
---|---|
AsEnumerable | Tidak |
Cast | Tidak |
Concat | Kueri yang tidak diurutkan yang memiliki Array atau sumber Daftar saja. |
DefaultIfEmpty | Tidak |
OfType | Tidak |
Reverse | Kueri yang tidak diurutkan yang memiliki Array atau sumber Daftar saja. |
Select | Tidak |
SelectMany | Tidak |
Skip | Tidak |
Take | Tidak |
Where | Tidak |
Semua operator kueri PLINQ lainnya mungkin mengabaikan opsi penggabungan yang disediakan pengguna. Beberapa operator kueri, misalnya, Reverse dan OrderBy, tidak dapat menghasilkan elemen apa pun hingga semua telah diproduksi dan diurutkan ulang. Oleh karena itu, ketika ParallelMergeOptions digunakan dalam kueri yang juga berisi operator seperti Reverse, perilaku penggabungan tidak akan diterapkan dalam kueri sampai operator tersebut telah menghasilkan hasilnya.
Kemampuan beberapa operator untuk menangani opsi penggabungan tergantung pada jenis rangkaian sumber, dan apakah operator AsOrdered digunakan sebelumnya dalam kueri. ForAll selalu NotBuffered ; segera menghasilkan elemen-elemennya. OrderBy selalu FullyBuffered; harus mengurutkan seluruh daftar sebelum menghasilkan.