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. Meskipun NotBuffered 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 daripada NotBuffered 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.

Lihat juga