Bagikan melalui


Opsi Penggabungan di PLINQ

Saat kueri dijalankan sebagai paralel, PLINQ mempartisi urutan 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 loop foreach (For Each di Visual Basic), maka hasil dari setiap utas harus digabungkan kembali ke dalam satu urutan. Jenis penggabungan yang dilakukan PLINQ bergantung pada operator yang ada dalam kueri. Misalnya, operator yang menerapkan urutan baru pada hasil harus menyimpan semua elemen dari semua thread. Dari perspektif utas yang mengonsumsi (yang juga merupakan pengguna aplikasi) kueri yang sepenuhnya memiliki buffer mungkin berjalan selama sejumlah waktu yang cukup lama sebelum menghasilkan hasil pertamanya. Operator lainnya, secara default, sebagian dibuffer; mereka mengeluarkan hasil dalam batch. Satu operator, ForAll tidak di-buffer secara default. Ini segera menghasilkan semua elemen dari semua utas.

Dengan menggunakan metode WithMergeOptions, seperti yang ditunjukkan dalam contoh berikut, Anda dapat memberikan petunjuk ke PLINQ untuk menunjukkan jenis penggabungan apa yang harus 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 hanya akan diabaikan. Dalam kebanyakan kasus, Anda tidak perlu menentukan opsi penggabungan untuk kueri PLINQ. Namun, dalam beberapa kasus Anda mungkin menemukan dengan menguji dan dengan mengukur bahwa kueri dieksekusi dengan optimal dalam mode non-default. Penggunaan umum dari opsi ini adalah untuk 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 menyebabkan setiap elemen yang diproses dikembalikan dari setiap utas segera setelah diproduksi. Perilaku ini dianalogikan dengan "streaming" output. AsOrdered Jika operator ada dalam kueri, NotBuffered pertahankan 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 mengumpulkan elemen ke dalam buffer dan kemudian secara berkala mengirimkan seluruh isi buffer sekaligus ke utas yang memprosesnya. Ini diibaratkan menghasilkan data sumber dalam "bagian" alih-alih menggunakan perilaku "streaming" dari NotBuffered. AutoBuffered mungkin membutuhkan waktu lebih lama daripada NotBuffered agar elemen pertama tersedia pada utas yang menerima. 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 dihasilkan. Ketika Anda menggunakan opsi ini, elemen pertama mungkin memerlukan waktu lebih lama untuk tersedia di utas konsumen, tetapi hasil lengkapnya mungkin masih dihasilkan lebih cepat daripada dengan menggunakan opsi lain.

Operator Kueri yang Mendukung Opsi Penggabungan

Tabel berikut mencantumkan operator yang mendukung semua mode opsi penggabungan, tunduk pada batasan yang ditentukan.

Pengoperasi Pembatasan
AsEnumerable Tidak ada
Cast Tidak ada
Concat Kueri yang tidak diurutkan yang hanya memiliki sumber Array atau Daftar.
DefaultIfEmpty Tidak ada
OfType Tidak ada
Reverse Kueri yang tidak diurutkan yang hanya memiliki sumber Array atau Daftar.
Select Tidak ada
SelectMany Tidak ada
Skip Tidak ada
Take Tidak ada
Where Tidak ada

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 sampai 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 setelah operator tersebut menghasilkan hasilnya.

Kemampuan beberapa operator untuk menangani opsi penggabungan tergantung pada jenis urutan sumber, dan apakah AsOrdered operator digunakan sebelumnya dalam kueri. ForAll selalu NotBuffered ; ia segera menghasilkan elemen-elemennya. OrderBy tetap FullyBuffered; harus mengurutkan seluruh daftar sebelum memberikan hasil.

Lihat juga