Seringkali saya ingin memeriksa apakah nilai yang diberikan cocok dengan satu dalam daftar (mis. Ketika memvalidasi):
if (!acceptedValues.Any(v => v == someValue))
{
// exception logic
}
Baru-baru ini, saya perhatikan ReSharper meminta saya untuk menyederhanakan pertanyaan ini menjadi:
if (acceptedValues.All(v => v != someValue))
{
// exception logic
}
Jelas, ini identik secara logis, mungkin sedikit lebih mudah dibaca (jika Anda telah melakukan banyak matematika), pertanyaan saya adalah: apakah ini menghasilkan hit kinerja?
Rasanya seperti itu seharusnya (yaitu .Any()
terdengar seperti itu arus pendek, sedangkan .All()
terdengar seperti itu tidak), tapi saya tidak punya apa-apa untuk membuktikan hal ini. Adakah yang memiliki pengetahuan yang lebih dalam tentang apakah pertanyaan akan menyelesaikan hal yang sama, atau apakah ReSharper membuat saya tersesat?
if (!sequence.Any(v => v == true))
. Jika Anda ingin melanjutkan hanya jika semuanya sesuai dengan spesifikasi tertentu:if (sequence.All(v => v < 10))
.Jawaban:
Implementasi
All
menurut ILSpy (seperti pada saya benar-benar pergi dan melihat, daripada "well, metode itu bekerja sedikit seperti ..." Saya mungkin lakukan jika kita membahas teori daripada dampaknya).Implementasi
Any
menurut ILSpy:Tentu saja, mungkin ada beberapa perbedaan halus dalam IL yang dihasilkan. Tapi tidak, tidak ada. IL hampir sama tetapi untuk inversi yang jelas untuk mengembalikan true pada pertandingan predikat versus kembali salah pada predikat mismatch.
Ini hanya linq-untuk-objek saja. Mungkin saja beberapa penyedia linq lain memperlakukan satu jauh lebih baik daripada yang lain, tetapi kemudian jika itu yang terjadi, itu cukup acak mana yang mendapat implementasi yang lebih optimal.
Tampaknya aturan itu hanya berlaku untuk seseorang yang merasa
if(determineSomethingTrue)
lebih sederhana dan lebih mudah dibaca daripadaif(!determineSomethingFalse)
. Dan dalam keadilan, saya pikir mereka sedikit banyak titik di mana saya sering menemukanif(!someTest)
* membingungkan ketika ada tes alternatif dengan verbositas dan kompleksitas yang sama yang akan kembali benar untuk kondisi yang ingin kita tindak lanjuti. Namun sungguh, secara pribadi saya tidak menemukan apa pun untuk mendukung salah satu dari dua alternatif yang Anda berikan, dan mungkin akan sedikit condong ke yang pertama jika predikatnya lebih rumit.* Tidak membingungkan karena saya tidak mengerti, tetapi membingungkan karena saya khawatir ada beberapa alasan halus untuk keputusan yang saya tidak mengerti, dan butuh beberapa lompatan mental untuk menyadari bahwa "tidak, mereka hanya memutuskan untuk melakukan dengan begitu, tunggu apa lagi yang saya cari dengan kode ini? ... "
sumber
Any
akan kembalifalse
dan karenanya!Any
akan kembalitrue
, jadi mereka identik.!test.Any(x => x.Key == 3 && x.Value == 1)
yang menggunakanAll
adalahtest.All(x => !(x.Key == 3 && x.Value == 1))
(yang memang setara dengantest.All(x => x.Key != 3 || x.Value != 1)
).Anda mungkin menemukan metode ekstensi ini membuat kode Anda lebih mudah dibaca:
Sekarang alih-alih yang asli
Anda bisa mengatakan
sumber
Keduanya akan memiliki kinerja yang identik karena keduanya menghentikan pencacahan setelah hasilnya dapat ditentukan -
Any()
pada item pertama yang lulus predikat dievaluasi ketrue
danAll()
pada item pertama predikat dievaluasifalse
.sumber
All
sirkuit pendek pada pertandingan pertama yang tidak cocok, jadi itu tidak masalah.Satu bidang kehalusan adalah itu
Adalah benar. Semua item dalam urutan adalah genap.
Untuk lebih lanjut tentang metode ini, lihat dokumentasi untuk Enumerable .
sumber
bool allEven = !Enumerable.Empty<int>().Any(i => i % 2 != 0)
itu benar juga.All()
menentukan apakah semua elemen urutan memenuhi suatu kondisi.Any()
menentukan apakah elemen dari urutan memenuhi syarat.sumber
Menurut tautan ini
sumber
Karena jawaban lain telah dibahas dengan baik: ini bukan tentang kinerja, ini tentang kejelasan.
Ada banyak dukungan untuk kedua opsi Anda:
Tetapi saya pikir ini mungkin mencapai dukungan yang lebih luas :
Cukup dengan menghitung boolean (dan menamainya) sebelum meniadakan apa pun, ini sangat jelas dalam pikiran saya.
sumber
Jika Anda melihat sumber Enumerable Anda akan melihat bahwa implementasi
Any
danAll
cukup dekat:Tidak ada cara yang satu metode untuk secara signifikan lebih cepat daripada yang lain karena satu-satunya perbedaan terletak pada negasi boolean, jadi lebih suka keterbacaan dibandingkan menang kinerja palsu.
sumber