di System.Linq
namespace, kita sekarang dapat memperluas IEnumerable kita untuk memiliki metode ekstensi Any () dan Count () .
Saya diberitahu baru-baru ini bahwa jika saya ingin memeriksa bahwa koleksi berisi 1 atau lebih item di dalamnya, saya harus menggunakan .Any()
metode ekstensi daripada .Count() > 0
metode ekstensi karena .Count()
metode ekstensi harus beralih melalui semua item.
Kedua, beberapa koleksi memiliki properti (bukan metode ekstensi) yaitu Count
atau Length
. Apakah lebih baik menggunakan itu, daripada .Any()
atau .Count()
?
ya / tidak?
Jawaban:
Jika Anda memulai dengan sesuatu yang memiliki
.Length
atau.Count
(sepertiICollection<T>
,IList<T>
,List<T>
, dll) - maka ini akan menjadi pilihan tercepat, karena tidak perlu pergi melaluiGetEnumerator()
/MoveNext()
/Dispose()
urutan yang dibutuhkan olehAny()
untuk memeriksa non-kosongIEnumerable<T>
urutan .Untuk hanya
IEnumerable<T>
, makaAny()
akan umumnya lebih cepat, karena hanya harus melihat satu iterasi. Namun, perhatikan bahwa implementasi LINQ-to-ObjectsCount()
tidak memeriksaICollection<T>
(menggunakan.Count
sebagai optimasi) - jadi jika sumber data dasar Anda secara langsung daftar / koleksi, tidak akan ada perbedaan besar. Jangan tanya saya mengapa itu tidak menggunakanICollection
...Tentu saja, jika Anda telah menggunakan LINQ untuk memfilternya dll (
Where
dll), Anda akan memiliki urutan berbasis iterator-blok, danICollection<T>
optimasi ini tidak berguna.Secara umum dengan
IEnumerable<T>
: tetap denganAny()
;-psumber
(somecollection.Count > 0)
? Apakah semua kode kami sebelum pengenalan metode LINQ .Any () sulit dipahami?someCollection.Count > 0
sejelassomeCollection.Any()
dan memiliki manfaat tambahan dari kinerja yang lebih besar dan tidak memerlukan LINQ. Memang, ini adalah kasus yang sangat sederhana dan konstruksi lainnya menggunakan operator LINQ akan menyampaikan maksud pengembang lebih jelas daripada opsi non-LINQ yang setara.Catatan: Saya menulis jawaban ini ketika Entity Framework 4 aktual. Inti dari jawaban ini adalah untuk tidak masuk ke pengujian sepele
.Any()
vs.Count()
kinerja. Intinya adalah memberi sinyal bahwa EF jauh dari sempurna. Versi yang lebih baru lebih baik ... tetapi jika Anda memiliki bagian dari kode yang lambat dan menggunakan EF, uji dengan TSQL langsung dan bandingkan kinerja daripada mengandalkan asumsi (yang.Any()
SELALU lebih cepat daripada.Count() > 0
).Sementara saya setuju dengan jawaban dan komentar yang paling banyak dipilih - terutama pada maksud
Any
sinyal maksud pengembang lebih baik daripadaCount() > 0
- Saya memiliki situasi di mana Hitungan lebih cepat berdasarkan urutan besarnya pada SQL Server (EntityFramework 4).Berikut adalah kueri dengan
Any
pengecualian batas waktu tersebut (pada ~ 200.000 catatan):Count
versi dieksekusi dalam hitungan milidetik:Saya perlu menemukan cara untuk melihat apa yang persis dihasilkan oleh kedua LINQ SQL - tapi jelas ada perbedaan kinerja yang sangat besar antara
Count
danAny
dalam beberapa kasus, dan sayangnya sepertinya Anda tidak bisa hanya bertahan denganAny
semua kasus.EDIT: Berikut ini adalah SQL yang dihasilkan. Keindahan seperti yang Anda lihat;)
ANY
:COUNT
:Tampaknya murni Dimana dengan EXIS bekerja jauh lebih buruk daripada menghitung Hitung dan kemudian melakukan Mana dengan Hitung == 0.
Beritahu saya jika Anda melihat kesalahan dalam temuan saya. Apa yang bisa diambil dari semua ini terlepas dari diskusi Apa pun vs Hitung adalah bahwa setiap LINQ yang lebih kompleks jauh lebih baik ketika ditulis ulang sebagai Prosedur Tersimpan;).
sumber
Karena ini adalah topik yang agak populer dan jawaban berbeda, saya harus melihat masalah baru.
Pengujian env: EF 6.1.3, SQL Server, catatan 300k
Model tabel :
Kode uji:
Hasil:
Any () ~ 3ms
Hitung () ~ 230 ms untuk kueri pertama, ~ 400 ms untuk kedua
Catatan:
Untuk kasus saya, EF tidak menghasilkan SQL seperti @Ben yang disebutkan dalam posnya.
sumber
Count() > 0
. : DEDIT: diperbaiki di EF versi 6.1.1. dan jawaban ini tidak lebih aktual
Untuk SQL Server dan EF4-6, Count () melakukan sekitar dua kali lebih cepat daripada Any ().
Ketika Anda menjalankan Table.Any (), itu akan menghasilkan sesuatu seperti ( waspada: jangan sakit otak mencoba memahaminya )
yang membutuhkan 2 pemindaian baris dengan kondisi Anda.
Saya tidak suka menulis
Count() > 0
karena itu menyembunyikan niat saya. Saya lebih suka menggunakan predikat khusus untuk ini:sumber
Tergantung, seberapa besar kumpulan data dan apa persyaratan kinerja Anda?
Jika bukan apa-apa, gunakan bentuk yang paling mudah dibaca, yang bagi saya adalah apa saja, karena bentuknya lebih pendek dan mudah dibaca daripada persamaan.
sumber
Tentang metode Count () , jika IEnumarable adalah ICollection , maka kami tidak dapat beralih di semua item karena kami dapat mengambil bidang Count ICollection , jika IEnumerable bukan ICollection, kami harus beralih di semua item menggunakan sementara dengan a MoveNext , lihat .NET Framework Code:
Referensi: Sumber Referensi Dapat Dihitung
sumber
Anda dapat melakukan tes sederhana untuk mengetahui hal ini:
Periksa nilai testCount dan testAny.
sumber
Count
diganti dengan metode Count () vs .Any () bukan properti. Anda perlu waktu iterasi.Jika Anda menggunakan Entity Framework dan memiliki tabel besar dengan banyak catatan Any () akan jauh lebih cepat. Saya ingat suatu kali saya ingin memeriksa untuk melihat apakah sebuah meja kosong dan ada jutaan baris. Butuh 20-30 detik untuk Count ()> 0 untuk menyelesaikan. Itu instan dengan Any () .
Any () dapat menjadi peningkatan kinerja karena mungkin tidak harus mengulang koleksi untuk mendapatkan sejumlah hal. Itu hanya harus mengenai salah satu dari mereka. Atau, untuk, katakanlah, LINQ-to-Entities, SQL yang dihasilkan akan JIKA ADA (...) daripada SELECT COUNT ... atau bahkan SELECT * ....
sumber