Aracılığıyla paylaş


PLINQ'te Sıra Koruması

PLINQ'ta amaç, doğruluğu korurken performansı en üst düzeye çıkarmaktır. Sorgu mümkün olduğunca hızlı çalışmalı ancak yine de doğru sonuçları üretmelidir. Bazı durumlarda doğruluk, kaynak dizisinin sırasının korunmasını gerektirir; ancak sıralama işlem açısından pahalı olabilir. Bu nedenle, PLINQ varsayılan olarak kaynak dizisinin sırasını korumaz. Bu bağlamda PLINQ, LINQ to SQL'e benzer, ancak sıralamayı koruyan LINQ to Objects'den farklı bir özelliktir.

Varsayılan davranışı değiştirmek için, kaynak dizideki AsOrdered işlecini kullanarak sıra korumayı açabilirsiniz. Daha sonra sorguda AsUnordered yöntemini kullanarak sıra korunmasını kapatabilirsiniz. Her iki yöntemle de sorgu, sorgunun paralel mi yoksa sıralı olarak mı yürütüleceğini belirleyen buluşsal yöntemlere göre işlenir. Daha fazla bilgi için bkz. PLINQ'de Hızlandırmayı Anlama .

Aşağıdaki örnek, sonuçları herhangi bir şekilde sıralamaya çalışmadan bir koşulla eşleşen tüm öğeler için filtreleyen sıralanmamış bir paralel sorguyu gösterir.

var cityQuery =
    (from city in cities.AsParallel()
     where city.Population > 10000
     select city).Take(1000);
Dim cityQuery = From city In cities.AsParallel()
                Where city.Population > 10000
                Take (1000)

Bu sorgu, koşula uyan kaynak dizideki ilk 1000 şehri değil, koşulu karşılayan 1000 şehirden oluşan bir küme oluşturmak zorunda değildir. PLINQ sorgu işleçleri, kaynak diziyi eşzamanlı görev olarak işlenen birden çok alt diziye böler. Sıra koruma belirtilmezse, her bölümden alınan sonuçlar rastgele bir sırada sorgunun bir sonraki aşamasına teslim edilir. Ayrıca, bir bölüm kalan öğeleri işlemeye devam etmeden önce sonuçlarının bir alt kümesini verebilir. Sonuçta elde edilen sıra her seferinde farklı olabilir. İşletim sisteminin iş parçacıklarını nasıl zamanladığına bağlı olduğundan uygulamanız bunu denetleyemiyor.

Aşağıdaki örnek, kaynak dizideki işlecini AsOrdered kullanarak varsayılan davranışı geçersiz kılar. Bu, yöntemin Take , koşulu karşılayan kaynak dizideki ilk 1000 şehri döndürmesini sağlar.

var orderedCities =
    (from city in cities.AsParallel().AsOrdered()
     where city.Population > 10000
     select city).Take(1000);

Dim orderedCities = From city In cities.AsParallel().AsOrdered()
                    Where city.Population > 10000
                    Take (1000)

Ancak, bölümler boyunca özgün sıralamayı izlemesi ve birleştirme sırasında sıralamanın tutarlı olduğundan emin olması gerektiğinden, bu sorgu büyük olasılıkla sıralanmamış sürüm kadar hızlı çalışmaz. Bu nedenle, yalnızca gerekli olduğunda ve yalnızca sorgunun gerektiren bölümleri için kullanmanızı AsOrdered öneririz. Sıra koruması artık gerekli olmadığında, sıra korumasını kapatmak için AsUnordered kullanın. Aşağıdaki örnek, iki sorgu oluşturarak bunu başarıyor.

var orderedCities2 =
    (from city in cities.AsParallel().AsOrdered()
     where city.Population > 10000
     select city).Take(1000);

var finalResult =
    from city in orderedCities2.AsUnordered()
    join p in people.AsParallel()
    on city.Name equals p.CityName into details
    from c in details
    select new
    {
        city.Name,
        Pop = city.Population,
        c.Mayor
    };

foreach (var city in finalResult) { /*...*/ }
Dim orderedCities2 = From city In cities.AsParallel().AsOrdered()
                     Where city.Population > 10000
                     Select city
                     Take (1000)

Dim finalResult = From city In orderedCities2.AsUnordered()
                  Join p In people.AsParallel() On city.Name Equals p.CityName
                  Select New With {.Name = city.Name, .Pop = city.Population, .Mayor = city.Mayor}

For Each city In finalResult
    Console.WriteLine(city.Name & ":" & city.Pop & ":" & city.Mayor)
Next

PLINQ'un sorgunun geri kalanı için order-imposing işleçleri tarafından üretilen bir sıranın sıralamasını koruduğuna dikkat edin. OrderBy ve ThenBy gibi işleçler, AsOrdered çağrısı ile takip ediliyormuş gibi değerlendirilir.

Sorgu İşleçleri ve Sıralama

Aşağıdaki sorgu operatörleri, sorgudaki sonraki tüm işlemlere veya AsUnordered çağrılana kadar sıra korumasını tanıtır:

Aşağıdaki PLINQ sorgu işleçleri bazı durumlarda doğru sonuçlar üretmek için sıralı kaynak dizileri gerektirebilir:

Bazı PLINQ sorgu işleçleri, kaynak sıralarının sıralı veya sırasız olmasına bağlı olarak farklı davranır. Aşağıdaki tabloda bu işleçler listelenmiştir.

Operatör Kaynak dizisi sıralandığında elde edilen sonuç Kaynak dizisi sıralanmadığında elde edilen sonuç
Aggregate Birleşmeli olmayan veya değişmeli olmayan işlemler için belirlenemez çıktı Birleşmeli olmayan veya değişmeli olmayan işlemler için belirlenemez çıktı
All Uygulanamaz Uygulanamaz
Any Uygulanamaz Uygulanamaz
AsEnumerable Uygulanamaz Uygulanamaz
Average Birleşmeli olmayan veya değişmeli olmayan işlemler için belirlenemez çıktı Birleşmeli olmayan veya değişmeli olmayan işlemler için belirlenemez çıktı
Cast Sıralı sonuçlar Sıralanmamış sonuçlar
Concat Sıralı sonuçlar Sıralanmamış sonuçlar
Count Uygulanamaz Uygulanamaz
DefaultIfEmpty Uygulanamaz Uygulanamaz
Distinct Sıralı sonuçlar Sıralanmamış sonuçlar
ElementAt Belirtilen öğeyi döndür Rastgele öğe
ElementAtOrDefault Belirtilen öğeyi döndür Rastgele öğe
Except Sıralanmamış sonuçlar Sıralanmamış sonuçlar
First Belirtilen öğeyi döndür Rastgele öğe
FirstOrDefault Belirtilen öğeyi döndür Rastgele öğe
ForAll Paralel olarak belirsiz bir şekilde yürütür Paralel olarak belirsiz bir şekilde yürütür
GroupBy Sıralı sonuçlar Sıralanmamış sonuçlar
GroupJoin Sıralı sonuçlar Sıralanmamış sonuçlar
Intersect Sıralı sonuçlar Sıralanmamış sonuçlar
Join Sıralı sonuçlar Sıralanmamış sonuçlar
Last Belirtilen öğeyi döndür Rastgele öğe
LastOrDefault Belirtilen öğeyi döndür Rastgele öğe
LongCount Uygulanamaz Uygulanamaz
Min Uygulanamaz Uygulanamaz
OrderBy Sırayı yeniden sıralar Yeni düzenli bölümü başlatır
OrderByDescending Sırayı yeniden sıralar Yeni düzenli bölümü başlatır
Range Geçerli değil (aynı varsayılan ile AsParallel ) Uygulanamaz
Repeat Geçerli değil (aynı varsayılan ayar olarak AsParallel) Uygulanamaz
Reverse Tersine çevirir Hiçbir şey yapmaz
Select Sıralı sonuçlar Sıralanmamış sonuçlar
Select (endekslenen) Sıralı sonuçlar Sıralanmamış sonuçlar.
SelectMany Sıralı sonuçlar. Sıralanmamış sonuçlar
SelectMany (endekslenen) Sıralı sonuçlar. Sıralanmamış sonuçlar.
SequenceEqual Sıralı karşılaştırma Sıralanmamış karşılaştırma
Single Uygulanamaz Uygulanamaz
SingleOrDefault Uygulanamaz Uygulanamaz
Skip İlk n öğeyi atlar Herhangi bir n öğeyi atlar
SkipWhile Sıralı sonuçlar. Determinist olmayan. Geçerli rastgele sırada SkipWhile işlemini gerçekleştirir
Sum Birleşmeli olmayan veya değişmeli olmayan işlemler için belirlenemez çıktı Birleşmeli olmayan veya değişmeli olmayan işlemler için belirlenemez çıktı
Take İlk n öğelerini alır Herhangi bir n öğeyi alır
TakeWhile Sıralı sonuçlar Determinist olmayan. Geçerli belirli bir sırada TakeWhile işlemini gerçekleştirir.
ThenBy Takviyeler OrderBy Takviyeler OrderBy
ThenByDescending Takviyeler OrderBy Takviyeler OrderBy
ToArray Sıralı sonuçlar Sıralanmamış sonuçlar
ToDictionary Uygulanamaz Uygulanamaz
ToList Sıralı sonuçlar Sıralanmamış sonuçlar
ToLookup Sıralı sonuçlar Sıralanmamış sonuçlar
Union Sıralı sonuçlar Sıralanmamış sonuçlar
Where Sıralı sonuçlar Sıralanmamış sonuçlar
Where (endekslenen) Sıralı sonuçlar Sıralanmamış sonuçlar
Zip Sıralı sonuçlar Sıralanmamış sonuçlar

Sıralanmamış sonuçlar etkin olarak karıştırılmaz; yalnızca kendilerine herhangi bir özel sıralama mantığı uygulanmaz. Bazı durumlarda, sıralanmamış bir sorgu kaynak dizinin sırasını koruyabilir. Dizine alınan Select işlecini kullanan sorgular için PLINQ, çıkış öğelerinin artan dizin sırasına göre çıkarılacağını garanti eder, ancak hangi dizinlerin hangi öğelere atanacağı konusunda hiçbir garanti vermemektedir.

Ayrıca bakınız