2011-02-16 27 views
14

Paralelleştirmek istediğim LinQ'dan nesneye basit bir sorgu yapıyorum, ancak ifadelerin sırasının önemli olup olmadığını merak ediyorum.C#: AsParallel - sipariş önemlidir?

örn.

IList<RepeaterItem> items; 

var result = items 
     .Select(item => item.FindControl("somecontrol")) 
     .Where(ctrl => SomeCheck(ctrl)) 
     .AsParallel(); 

vs

var result = items 
     .AsParallel() 
     .Select(item => item.FindControl("somecontrol")) 
     .Where(ctrl => SomeCheck(ctrl)); 

herhangi bir fark olur mu?

cevap

22

Kesinlikle. İlk durumda, izdüşüm ve filtreleme seri olarak yapılacak ve sadece ve daha sonra herhangi bir şeye paralel olacaktır. İkinci durumda, hem yansıtma hem de filtreleme paralel olarak gerçekleşecektir.

İlk sürümü kullanmak için belirli bir nedeniniz yoksa (ör. Projeksiyonda iplik ilgisi veya başka bir tuhaflık varsa) ikinciyi kullanmalısınız.

DÜZENLEME: İşte bazı test kodları. Kusurlu gibi birçok kriterler vardır, ama sonuç oldukça kesin şunlardır:

using System; 
using System.Diagnostics; 
using System.Linq; 
using System.Threading; 

class Test 
{ 
    static void Main() 
    { 
     var query = Enumerable.Range(0, 1000) 
           .Select(SlowProjection) 
           .Where(x => x > 10) 
           .AsParallel(); 
     Stopwatch sw = Stopwatch.StartNew(); 
     int count = query.Count(); 
     sw.Stop(); 
     Console.WriteLine("Count: {0} in {1}ms", count, 
          sw.ElapsedMilliseconds); 

     query = Enumerable.Range(0, 1000) 
          .AsParallel() 
          .Select(SlowProjection) 
          .Where(x => x > 10); 
     sw = Stopwatch.StartNew(); 
     count = query.Count(); 
     sw.Stop(); 
     Console.WriteLine("Count: {0} in {1}ms", count, 
          sw.ElapsedMilliseconds); 
    } 

    static int SlowProjection(int input) 
    { 
     Thread.Sleep(100); 
     return input; 
    } 
} 

Sonuçlar:

Count: 989 in 100183ms 
Count: 989 in 13626ms 

Şimdi orada pfx oluyor sezgisel bir sürü, ama oldukça açık olduğunu ilk sonuç henüz paralelleştirilmemiş, ikincisi ise.

+0

+1. Ben de ilk başta gitmek zorunda (ikna 2), ama emin olmak için her zaman daha iyiydi :-) – Steffen

+1

@Steffen: Ben sadece fibs söylüyorum emin olmak için bir test çalıştırıyorum :) –

+0

test ediyor musun Kendimi test etmeyi düşünüyordum, ama bununla ilgili tam olarak nasıl olacağından emin değildim. – Steffen

1

Sadece performansta değil, önemli. İlk ve ikinci sorguların sonucu eşit değildir. Paralel işlemeye ve orijinal sırayı koruyacak bir çözüm var. AsParallel().AsOrdered()'u kullanın. Üçüncü sorgu bunu gösterir.

var SlowProjection = new Func<int, int>((input) => { Thread.Sleep(100); return input; }); 

var Measure = new Action<string, Func<List<int>>>((title, measure) => 
{ 
    Stopwatch sw = Stopwatch.StartNew(); 
    var result = measure(); 
    sw.Stop(); 
    Console.Write("{0} Time: {1}, Result: ", title, sw.ElapsedMilliseconds); 
    foreach (var entry in result) Console.Write(entry + " ");   
}); 

Measure("Sequential",() => Enumerable.Range(0, 30) 
    .Select(SlowProjection).Where(x => x > 10).ToList()); 
Measure("Parallel",() => Enumerable.Range(0, 30).AsParallel() 
    .Select(SlowProjection).Where(x => x > 10).ToList()); 
Measure("Ordered",() => Enumerable.Range(0, 30).AsParallel().AsOrdered() 
    .Select(SlowProjection).Where(x => x > 10).ToList()); 

Sonuç:

Sequential Time: 6699, Result: 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 
Parallel Time: 1462, Result: 12 16 22 25 29 14 17 21 24 11 15 18 23 26 13 19 20 27 28 
Ordered Time: 1357, Result: 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 

Bu konuda şaşırdım ama sonuç 10+ deneme sürüşünden sonra tutarlı olmuştur. Biraz araştırdım ve .Net 4.0'da bir "hata" olduğu ortaya çıktı. . 4.5 AsParallel() AsParallel daha yavaş olduğu doğru değildir() AsOrdered() in

Referans buradadır: Mükemmel

http://msdn.microsoft.com/en-us/library/dd460677(v=vs.110).aspx

+0

.AsOrdered'in() neden daha hızlı olduğunu ya da sadece bir kez daha kaçmasının neden olduğunu biliyor musunuz? Siparişi sürdürmenin, yürütme hızını artıracağını düşünmüyorum, azaltmak değil. –

+1

Ben de şaşırdım ama sonuç birden fazla (10+) test çalışmasında tutarlıydı. Nedenini bilmiyorum ve araştırmıyordum - soruyla ilgili değildi. :-) – Kobor42