Pada dasarnya, seperti yang dinyatakan dalam pertanyaan ... apakah urutan fungsi LINQ penting dalam hal kinerja ? Jelas hasilnya masih harus identik ...
Contoh:
myCollection.OrderBy(item => item.CreatedDate).Where(item => item.Code > 3);
myCollection.Where(item => item.Code > 3).OrderBy(item => item.CreatedDate);
Keduanya memberi saya hasil yang sama, tetapi dalam urutan LINQ yang berbeda. Saya menyadari bahwa menata ulang beberapa item akan menghasilkan hasil yang berbeda, dan saya tidak mengkhawatirkan hal itu. Yang menjadi perhatian utama saya adalah mengetahui apakah, dalam mendapatkan hasil yang sama, pemesanan dapat memengaruhi kinerja. Dan, tidak hanya pada panggilan 2 LINQ yang saya lakukan (OrderBy, Where), tetapi pada panggilan LINQ mana pun.
c#
performance
linq
michael
sumber
sumber
var query = myCollection.OrderBy(item => item.Code).Where(item => item.Code == 3);
.Jawaban:
Ini akan tergantung pada penyedia LINQ yang digunakan. Untuk LINQ ke Objects, itu pasti bisa membuat perbedaan besar . Asumsikan kita benar-benar punya:
Itu membutuhkan seluruh koleksi untuk diurutkan dan kemudian difilter. Jika kita memiliki sejuta item, hanya satu yang memiliki kode lebih dari 3, kita akan membuang banyak waktu untuk memesan hasil yang akan dibuang.
Bandingkan dengan operasi terbalik, dengan memfilter terlebih dahulu:
Kali ini kami hanya mengurutkan hasil yang difilter, yang dalam contoh kasus "hanya satu item yang cocok dengan filter" akan jauh lebih efisien - baik dalam waktu maupun ruang.
Itu juga bisa membuat perbedaan dalam apakah kueri dijalankan dengan benar atau tidak. Mempertimbangkan:
Tidak apa-apa - kita tahu kita tidak akan pernah membagi dengan 0. Tetapi jika kita melakukan pengurutan sebelum pemfilteran, kueri akan memunculkan pengecualian.
sumber
Iya.
Tapi persis apa yang perbedaan kinerja tergantung pada bagaimana pohon ekspresi yang mendasari dievaluasi oleh penyedia LINQ.
Misalnya, kueri Anda mungkin dieksekusi lebih cepat untuk kedua kalinya (dengan klausa WHERE terlebih dahulu) untuk LINQ-to-XML, tetapi lebih cepat pertama kali untuk LINQ-to-SQL.
Untuk mengetahui dengan tepat apa perbedaan kinerja, kemungkinan besar Anda ingin membuat profil aplikasi Anda. Namun, seperti biasa dengan hal-hal seperti itu, pengoptimalan prematur biasanya tidak sepadan dengan usaha - Anda mungkin menemukan masalah selain kinerja LINQ yang lebih penting.
sumber
Dalam contoh khusus Anda, ini dapat membuat perbedaan pada kinerja.
Kueri pertama:
OrderBy
Panggilan Anda perlu mengulang seluruh urutan sumber, termasuk item yang nilainyaCode
3 atau kurang. TheWhere
klausul kemudian juga perlu iterate seluruh memerintahkan urutan.Kueri kedua:
Where
Panggilan membatasi urutan hanya untuk itemCode
yang lebih besar dari 3.OrderBy
Panggilan kemudian hanya perlu melintasi urutan yang dikurangi yang dikembalikan olehWhere
panggilan.sumber
Dalam Linq-To-Objects:
Penyortiran agak lambat dan menggunakan
O(n)
memori.Where
di sisi lain relatif cepat dan menggunakan memori yang konstan. Jadi mengerjakanWhere
lebih dulu akan lebih cepat, dan untuk koleksi besar secara signifikan lebih cepat.Tekanan memori yang berkurang juga bisa menjadi signifikan, karena alokasi pada tumpukan objek yang besar (bersama dengan koleksinya) relatif mahal menurut pengalaman saya.
sumber
Perhatikan bahwa ini sebenarnya tidak benar - khususnya, dua baris berikut akan memberikan hasil yang berbeda (untuk sebagian besar penyedia / kumpulan data):
sumber
Perlu dicatat bahwa Anda harus berhati-hati saat mempertimbangkan cara mengoptimalkan kueri LINQ. Misalnya, jika Anda menggunakan versi deklaratif LINQ untuk melakukan hal berikut:
Jika, karena alasan apa pun, Anda memutuskan untuk "mengoptimalkan" kueri dengan menyimpan rata-rata ke dalam variabel terlebih dahulu, Anda tidak akan mendapatkan hasil yang diinginkan:
Saya tahu tidak banyak orang menggunakan LINQ deklaratif untuk objek, tetapi ini adalah bahan pemikiran yang baik.
sumber
Itu tergantung pada relevansinya. Misalkan jika Anda memiliki sangat sedikit item dengan Kode = 3, maka pesanan berikutnya akan mengerjakan sejumlah kecil koleksi untuk mendapatkan pesanan berdasarkan tanggal.
Sedangkan jika Anda memiliki banyak item dengan CreatedDate yang sama, maka pesanan berikutnya akan bekerja pada kumpulan koleksi yang lebih besar untuk mendapatkan pesanan berdasarkan tanggal.
Jadi, dalam kedua kasus tersebut akan ada perbedaan kinerja
sumber