SORU
20 AĞUSTOS 2013, Salı


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; }
}

Aslında çok daha büyük ama bu sorun (tuhaflık) yeniden oluşturur.

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.

(Daha iyi bir Fikri olarak göndermek için geldiğini düşündüm 100 çizgiler.)
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ü Wherehala(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 vs Select and Where.

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.

Metin duvardan okuma için teşekkürler! Eğer, here's eğer ilgileniyorsanız ayrıca, Değiştirilmiş Sürümü olan Excel götüren CSV olarak kaydeder.

CEVAP
20 AĞUSTOS 2013, Salı


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 maliyeti
  • cost(yield) Select sürümünü kullanan basit yineleyici daha karmaşık olan where 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.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Besnik Ibrahimi

    Besnik Ibrah

    27 Mart 2010
  • Bryan Smith

    Bryan Smith

    12 Mart 2006
  • FOSDEM

    FOSDEM

    13 Ocak 2009