Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Dalam PLINQ, tujuannya adalah untuk memaksimalkan performa sambil mempertahankan kebenaran. Kueri harus berjalan secepat mungkin tetapi masih menghasilkan hasil yang benar. Dalam beberapa kasus, ketepatan memerlukan urutan sumber untuk dipertahankan; namun, pengurutan bisa memerlukan biaya komputasi tinggi. Oleh karena itu, secara default, PLINQ tidak mempertahankan urutan sumber. Dalam hal ini, PLINQ menyerupai LINQ ke SQL, tetapi tidak seperti LINQ ke Objek, yang mempertahankan urutan.
Untuk mengganti perilaku default, Anda dapat mengaktifkan pelestarian urutan dengan menggunakan operator AsOrdered pada rangkaian sumber. Anda kemudian dapat menonaktifkan pelestarian pesanan nanti dalam kueri dengan menggunakan metode AsUnordered. Dengan kedua metode, kueri diproses berdasarkan heuristik yang menentukan apakah akan menjalankan kueri sebagai paralel atau berurutan. Untuk informasi selengkapnya, lihat Memahami Speedup di PLINQ.
Contoh berikut menunjukkan kueri paralel yang tidak diurutkan yang memfilter semua elemen yang cocok dengan kondisi, tanpa mencoba mengurutkan hasilnya dengan cara apa pun.
var cityQuery =
(from city in cities.AsParallel()
where city.Population > 10000
select city).Take(1000);
Dim cityQuery = From city In cities.AsParallel()
Where city.Population > 10000
Take (1000)
Kueri ini tidak selalu menghasilkan 1000 kota pertama dalam urutan sumber yang memenuhi kondisi, melainkan beberapa set 1000 kota yang memenuhi kondisi. Operator kueri PLINQ mempartisi urutan sumber ke dalam beberapa urutan berikutnya yang diproses sebagai tugas bersamaan. Jika retensi urutan tidak ditentukan, hasil dari setiap partisi diserahkan ke tahap berikutnya dari kueri dalam urutan sembarang. Selain itu, partisi dapat menghasilkan subset hasilnya sebelum terus memproses elemen yang tersisa. Urutan yang dihasilkan mungkin berbeda setiap saat. Aplikasi Anda tidak dapat mengontrol ini karena tergantung pada cara sistem operasi menjadwalkan thread.
Contoh berikut mengambil alih perilaku default dengan menggunakan AsOrdered operator pada urutan sumber. Ini memastikan bahwa metode Take mengembalikan 1000 kota pertama dalam deretan sumber yang memenuhi kondisi.
var orderedCities =
(from city in cities.AsParallel().AsOrdered()
where city.Population > 10000
select city).Take(1000);
Dim orderedCities = From city In cities.AsParallel().AsOrdered()
Where city.Population > 10000
Take (1000)
Namun, kueri ini mungkin tidak berjalan secepat versi yang tidak diurutkan karena harus melacak urutan asli di seluruh partisi dan pada waktu penggabungan memastikan bahwa pengurutan konsisten. Oleh karena itu, kami sarankan Anda hanya menggunakan AsOrdered saat diperlukan, dan hanya untuk bagian kueri yang memerlukannya. Ketika preservasi pesanan tidak lagi diperlukan, gunakan AsUnordered untuk menonaktifkannya. Contoh berikut mencapai ini dengan menyusun dua kueri.
var orderedCities2 =
(from city in cities.AsParallel().AsOrdered()
where city.Population > 10000
select city).Take(1000);
var finalResult =
from city in orderedCities2.AsUnordered()
join p in people.AsParallel()
on city.Name equals p.CityName into details
from c in details
select new
{
city.Name,
Pop = city.Population,
c.Mayor
};
foreach (var city in finalResult) { /*...*/ }
Dim orderedCities2 = From city In cities.AsParallel().AsOrdered()
Where city.Population > 10000
Select city
Take (1000)
Dim finalResult = From city In orderedCities2.AsUnordered()
Join p In people.AsParallel() On city.Name Equals p.CityName
Select New With {.Name = city.Name, .Pop = city.Population, .Mayor = city.Mayor}
For Each city In finalResult
Console.WriteLine(city.Name & ":" & city.Pop & ":" & city.Mayor)
Next
Perhatikan bahwa PLINQ mempertahankan urutan yang dihasilkan oleh operator yang memberlakukan pesanan untuk sisa kueri. Dengan kata lain, operator seperti OrderBy dan ThenBy diperlakukan seolah-olah mereka diikuti oleh panggilan ke AsOrdered.
Operator dan Penyusunan Kueri
Operator kueri berikut memperkenalkan pelestarian pesanan ke dalam semua operasi berikutnya dalam kueri, atau sampai AsUnordered dipanggil:
Operator kueri PLINQ berikut mungkin dalam beberapa kasus memerlukan urutan sumber yang diurutkan untuk menghasilkan hasil yang benar:
Beberapa operator kueri PLINQ bersifat berbeda, tergantung pada apakah urutan sumbernya diurutkan atau tidak diurutkan. Tabel berikut mencantumkan operator ini.
| Pengoperasi | Hasil ketika urutan sumber diurutkan | Hasil ketika urutan sumber tidak diurutkan |
|---|---|---|
| Aggregate | Output nondeterministik untuk operasi nonasosiatif atau nonkomutatif | Output nondeterministik untuk operasi nonasosiatif atau nonkomutatif |
| All | Tidak berlaku | Tidak berlaku |
| Any | Tidak berlaku | Tidak berlaku |
| AsEnumerable | Tidak berlaku | Tidak berlaku |
| Average | Output nondeterministik untuk operasi nonasosiatif atau nonkomutatif | Output nondeterministik untuk operasi nonasosiatif atau nonkomutatif |
| Cast | Hasil yang diurutkan | Hasil yang tidak diurutkan |
| Concat | Hasil yang diurutkan | Hasil yang tidak diurutkan |
| Count | Tidak berlaku | Tidak berlaku |
| DefaultIfEmpty | Tidak berlaku | Tidak berlaku |
| Distinct | Hasil yang diurutkan | Hasil yang tidak diurutkan |
| ElementAt | Mengembalikan elemen yang ditentukan | Elemen arbitrer |
| ElementAtOrDefault | Mengembalikan elemen yang ditentukan | Elemen arbitrer |
| Except | Hasil yang tidak diurutkan | Hasil yang tidak diurutkan |
| First | Mengembalikan elemen yang ditentukan | Elemen arbitrer |
| FirstOrDefault | Mengembalikan elemen yang ditentukan | Elemen arbitrer |
| ForAll | Menjalankan secara nondeterministik secara paralel | Menjalankan secara nondeterministik secara paralel |
| GroupBy | Hasil yang diurutkan | Hasil yang tidak diurutkan |
| GroupJoin | Hasil yang diurutkan | Hasil yang tidak diurutkan |
| Intersect | Hasil yang diurutkan | Hasil yang tidak diurutkan |
| Join | Hasil yang diurutkan | Hasil yang tidak diurutkan |
| Last | Mengembalikan elemen yang ditentukan | Elemen arbitrer |
| LastOrDefault | Mengembalikan elemen yang ditentukan | Elemen arbitrer |
| LongCount | Tidak berlaku | Tidak berlaku |
| Min | Tidak berlaku | Tidak berlaku |
| OrderBy | Menyusun ulang urutan | Memulai bagian berurutan baru |
| OrderByDescending | Menyusun ulang urutan | Memulai bagian berurutan baru |
| Range | Tidak berlaku (default yang sama dengan AsParallel ) | Tidak berlaku |
| Repeat | Tidak berlaku (default yang sama dengan AsParallel) | Tidak berlaku |
| Reverse | Membalikkan | Tidak melakukan apa-apa |
| Select | Hasil yang diurutkan | Hasil yang tidak diurutkan |
| Select (terindeks) | Hasil yang diurutkan | Hasil yang tidak diurutkan. |
| SelectMany | Hasil yang diurutkan. | Hasil yang tidak diurutkan |
| SelectMany (terindeks) | Hasil yang diurutkan. | Hasil yang tidak diurutkan. |
| SequenceEqual | Perbandingan yang diurutkan | Perbandingan yang tidak diurutkan |
| Single | Tidak berlaku | Tidak berlaku |
| SingleOrDefault | Tidak berlaku | Tidak berlaku |
| Skip | Melompati elemen n pertama | Melompati elemen n apa pun |
| SkipWhile | Hasil yang diurutkan. | Nondeterministik. Melakukan fungsi SkipWhile pada urutan acak saat ini |
| Sum | Output nondeterministik untuk operasi nonasosiatif atau nonkomutatif | Output nondeterministik untuk operasi nonasosiatif atau nonkomutatif |
| Take | Mengambil elemen pertama n |
Mengambil elemen apa pun n |
| TakeWhile | Hasil yang diurutkan | Nondeterministik. Menggunakan fungsi TakeWhile pada urutan acak saat ini |
| ThenBy | Suplemen OrderBy |
Suplemen OrderBy |
| ThenByDescending | Suplemen OrderBy |
Suplemen OrderBy |
| ToArray | Hasil yang diurutkan | Hasil yang tidak diurutkan |
| ToDictionary | Tidak berlaku | Tidak berlaku |
| ToList | Hasil yang diurutkan | Hasil yang tidak diurutkan |
| ToLookup | Hasil yang diurutkan | Hasil yang tidak diurutkan |
| Union | Hasil yang diurutkan | Hasil yang tidak diurutkan |
| Where | Hasil yang diurutkan | Hasil yang tidak diurutkan |
| Where (terindeks) | Hasil yang diurutkan | Hasil yang tidak diurutkan |
| Zip | Hasil yang diurutkan | Hasil yang tidak diurutkan |
Hasil tanpa urutan tidak diacak aktif; tidak menerapkan logika pengurutan khusus. Dalam beberapa kasus, kueri yang tidak diurutkan dapat mempertahankan urutan sumber. Untuk kueri yang menggunakan operator Pilih terindeks, PLINQ menjamin bahwa elemen output akan keluar dalam urutan peningkatan indeks, tetapi tidak membuat jaminan tentang indeks mana yang akan ditetapkan ke elemen mana.