Neden sadece Seçmek iyi performans Nerede?
Bir sınıf, bu gibi:
public class MyClass
{
public int Value { get; set; }
public bool IsValid { get; set; }
}
Toplamı örnek geçerli olduğu Value
almak istiyorum. Şimdiye kadar, bu iki çözümü buldum.
İlki şu:
int result = myCollection.Where(mc => mc.IsValid).Select(mc => mc.Value).Sum();
İkincisi, ancak, bu
int result = myCollection.Select(mc => mc.IsValid ? mc.Value : 0).Sum();
En etkili yöntem almak istiyorum. Ben, ilk başta, ikincisi daha verimli olacağını düşündüm. Bana teorik kısmı gitmeye başladı "Eh, O(n m m), diğeri ise bir O(n n). daha sonra İlki ikinci bir daha az ile gerçekleştirmek gerekirken daha sakatlar ile daha iyi yapabilir. Eşit gerçekleştirmek olacağını düşündüm. EDİT: Ve @Martin Nerede ve Seçmek birleştirildi, aslında O olmalıdır(m n) göstermiştir. Eğer aşağıya bakarsanız, ancak, bu ilgili değil gibi görünüyor.
So I put it to the test.
Sonuçlar ilginç.
0% kravat hoşgörü ile
Ölçekler Select
ve ~30 puan Where
, nimetine.
How much do you want to be the disambiguation percentage?
0
Starting benchmarking.
Ties: 0
Where Select: 65
Select: 36
2% kravat tolerans:
Aynı şey, bazı %2 içinde olduğu dışında. Bu hata en az bir marj olduğunu söyleyebilirim. Select
Where
şimdi ~20 Puan, sadece bir kurşun var.
How much do you want to be the disambiguation percentage?
2
Starting benchmarking.
Ties: 6
Where Select: 58
Select: 37
5% kravat tolerans:
Bu hatanın benim en yüksek teminat olarak söyleyebilirim. Biraz daha iyi Select
ama pek bir şey yapar.
How much do you want to be the disambiguation percentage?
5
Starting benchmarking.
Ties: 17
Where Select: 53
Select: 31
10% kravat tolerans:
Bu hata benim marjı bir şey değil, ama yine de sonucu merak ediyorum. Select
Where
yirmi nokta ipucu verir, çünkü bir süredir vardı.
How much do you want to be the disambiguation percentage?
10
Starting benchmarking.
Ties: 36
Where Select: 44
Select: 21
25% tolerans kravat:
Bu şekildeyolhata benim marj, ama hala sonuç ilgileniyorum, Select
çünkü Where
hala(yaklaşık) 20 Puan önünde liderliklerini devam et. Bir farklı sayıda outclassing gibi görünüyor, ve bu sadece bir ipucu veriyor.
How much do you want to be the disambiguation percentage?
25
Starting benchmarking.
Ties: 85
Where Select: 16
Select: 0
Şimdi, 20 Puan önünde lider olmaya mecburlar hem ortanca geldiğini tahmin ediyorumetrafındaaynı performans. Deneyin ve günlük olabilirim, ama almak için bilgi bir sürü olacaktır. Bir grafik daha iyi olurdu, sanırım.
Benim yaptığım da buydu.
Select
satır sürekli (beklenen) tutar ve Select Where
satır (beklenen) tırmanan gösterir. Ancak, ne beni sasirtiyor neden gelmiyor karşılamak ile Select
50 ya da daha önce: aslında beklediğim'den önceki 50, figüranlık numaralandırıcısı olmalı yaratılmış Select
Where
. Bu 20 Puan önde gösteriyor, ama açıklamıyor. Bu, sanırım, benim sorum en önemli nokta oldu.
Neden böyle davranıyor mu? Ona güvenmeli miyim? Diğer mu yoksa bu mu kullanmalıyım?
@Yorumlarda bahsedilen KingKong da Sum
'lambda. alır s aşırı kullanabilirsiniz İki seçeneğim var şimdi bunun değiştirilmesi için:
İlk:
int result = myCollection.Where(mc => mc.IsValid).Sum(mc => mc.Value);
İkinci:
int result = myCollection.Sum(mc => mc.IsValid ? mc.Value : 0);
Ben biraz daha kısa olacak, ama ben hazırım
How much do you want to be the disambiguation percentage?
0
Starting benchmarking.
Ties: 0
Where: 60
Sum: 41
How much do you want to be the disambiguation percentage?
2
Starting benchmarking.
Ties: 8
Where: 55
Sum: 38
How much do you want to be the disambiguation percentage?
5
Starting benchmarking.
Ties: 21
Where: 49
Sum: 31
How much do you want to be the disambiguation percentage?
10
Starting benchmarking.
Ties: 39
Where: 41
Sum: 21
How much do you want to be the disambiguation percentage?
25
Starting benchmarking.
Ties: 85
Where: 16
Sum: 0
Yirmi puan önde hala orada mı, yani Where
Select
kombinasyonu @yorum Marcin tarafından işaret ile yapmak zorunda değil.
CEVAP
Select
bir kez tüm yineler ve her madde için, Koşullu dal (geçerlilik denetimi) ve
bir işlem gerçekleştirir.
Where Select
geçersiz öğeleri (37* *mi onları değil) atlar bir yineleyici, geçerli öğeler yalnızca
bir sahne oluşturur.
Yani, Select
bir maliyeti vardır:
t(s) = n * ( cost(check valid) cost( ) )
Ve Where Select
:
t(ws) = n * ( cost(check valid) p(valid) * (cost(yield) cost( )) )
Nereye:
p(valid)
listedeki bir öğeyi geçerli olduğunu olasılığıdır.cost(check valid)
geçerliliğini kontrol eden şube maliyeticost(yield)
Select
sürümünü kullanan basit yineleyici daha karmaşık olanwhere
yineleyici, yeni devlet inşa maliyeti.
Gördüğünüz gibi, belirli bir* *48, Select
sürümü Where Select
sürüm bir değişken olarak p(valid)
ile doğrusal bir denklem ise bir sabittir. Bu giderlerin gerçek değerleri iki satır kesiştiği noktayı belirlemek ve cost(yield)
cost( )
, farklı olabilir, çünkü mutlaka p(valid)
=0,5 bilgisayar yok.
Neden şablonlar sadece başlık dosyasın...
Neden Javascript sadece IE Geliştirici...
Neden yok't bu kod sadece A-Z ara...
Ben tüm ASP.Net Web siteleri yavaş ve ...
Neden sadece son değişkenleri anonim s...