Megosztás a következőn keresztül:


Rendelésmegőrzés a PLINQ-ban

A PLINQ-ban a cél a teljesítmény maximalizálása a helyesség fenntartása mellett. A lekérdezésnek a lehető leggyorsabban kell futnia, de továbbra is a megfelelő eredményeket kell eredményeznie. Bizonyos esetekben a helyesség megköveteli a forrásütemezés sorrendjének megőrzését; a megrendelés azonban számításilag költséges lehet. Ezért a PLINQ alapértelmezés szerint nem őrzi meg a forrásütemezés sorrendjét. Ebben a tekintetben a PLINQ a LINQ-hoz hasonlít az SQL-hez, de nem hasonlít a LINQ-ra az objektumokhoz, ami megőrzi a sorrendet.

Az alapértelmezett viselkedés felülbírálásához bekapcsolhatja a sorrend megőrzését a AsOrdered forrásütemezés operátorával. Ezután a metódussal AsUnordered kikapcsolhatja a rendelések megőrzését a lekérdezés későbbi részében. Mindkét módszer esetén a lekérdezés feldolgozása a heurisztika alapján történik, amely meghatározza, hogy a lekérdezést párhuzamosként vagy szekvenciálisként kell-e végrehajtani. További információ: Understanding Speedup in PLINQ.

Az alábbi példa egy rendezetlen párhuzamos lekérdezést mutat be, amely a feltételnek megfelelő összes elemre szűr anélkül, hogy bármilyen módon megpróbálná rendezni az eredményeket.

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)

Ez a lekérdezés nem feltétlenül hozza létre az első 1000 várost a forrásütemezésben, amely megfelel a feltételnek, hanem néhány 1000 városból, amelyek megfelelnek a feltételnek. A PLINQ lekérdezési operátorok több részügyre particionálják a forrásütemezést, amelyeket egyidejű feladatként dolgoznak fel. Ha a sorrend megőrzése nincs megadva, az egyes partíciók eredményei tetszőleges sorrendben kerülnek átadásra a lekérdezés következő szakaszára. A partíciók az eredmények egy részhalmazát is eredményezhetik, mielőtt folytatják a fennmaradó elemek feldolgozását. Az eredményként kapott sorrend minden alkalommal eltérő lehet. Az alkalmazás ezt nem tudja szabályozni, mert attól függ, hogy az operációs rendszer hogyan ütemezi a szálakat.

Az alábbi példa felülírja az alapértelmezett viselkedést a AsOrdered forrásütemezés operátorának használatával. Ez biztosítja, hogy a Take metódus a forrásütemezés első 1000 városát adja vissza, amelyek megfelelnek a feltételnek.

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)

Ez a lekérdezés azonban valószínűleg nem fut olyan gyorsan, mint a rendezetlen verzió, mert nyomon kell követnie az eredeti sorrendet a partíciókon, és az egyesítéskor gondoskodnia kell arról, hogy a rendezés konzisztens legyen. Ezért azt javasoljuk, hogy csak akkor használja AsOrdered , ha szükséges, és csak a lekérdezés azon részeire, amelyek megkövetelik. Ha a rendelések megőrzésére már nincs szükség, kapcsolja AsUnordered ki. Az alábbi példa ezt két lekérdezés írásával éri el.

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

Vegye figyelembe, hogy a PLINQ megőrzi egy sorrendbe állítva a lekérdezés többi részében a rendelési impozáns operátorok által előállított sorrendet. Más szóval az olyan operátorokat, mint OrderBy például a ThenBy rendszer úgy kezeli őket, mintha egy hívás AsOrderedkövette volna őket.

Lekérdezési operátorok és rendezés

A következő lekérdezési operátorok a lekérdezés minden további műveletében bevezetik a sorrend megőrzését, vagy amíg meg nem AsUnordered hívják:

A következő PLINQ-lekérdezési operátorok bizonyos esetekben rendezett forrásütemezéseket igényelhetnek a helyes eredmények eléréséhez:

Egyes PLINQ-lekérdezési operátorok eltérően viselkednek attól függően, hogy a forrásütemezés rendezett vagy rendezetlen. Az alábbi táblázat felsorolja ezeket az operátorokat.

Operátor A forrásütemezés sorrendjének eredménye Eredmény, ha a forrásütemezés rendezetlen
Aggregate Nemdeterminista kimenet nem társító vagy nem kommutatív műveletekhez Nemdeterminista kimenet nem társító vagy nem kommutatív műveletekhez
All Nem alkalmazható Nem alkalmazható
Any Nem alkalmazható Nem alkalmazható
AsEnumerable Nem alkalmazható Nem alkalmazható
Average Nemdeterminista kimenet nem társító vagy nem kommutatív műveletekhez Nemdeterminista kimenet nem társító vagy nem kommutatív műveletekhez
Cast Rendezett eredmények Rendezetlen eredmények
Concat Rendezett eredmények Rendezetlen eredmények
Count Nem alkalmazható Nem alkalmazható
DefaultIfEmpty Nem alkalmazható Nem alkalmazható
Distinct Rendezett eredmények Rendezetlen eredmények
ElementAt Megadott elem visszaadva Tetszőleges elem
ElementAtOrDefault Megadott elem visszaadva Tetszőleges elem
Except Rendezetlen eredmények Rendezetlen eredmények
First Megadott elem visszaadva Tetszőleges elem
FirstOrDefault Megadott elem visszaadva Tetszőleges elem
ForAll Nemdeterminisztikusan, párhuzamosan hajtja végre Nemdeterminisztikusan, párhuzamosan hajtja végre
GroupBy Rendezett eredmények Rendezetlen eredmények
GroupJoin Rendezett eredmények Rendezetlen eredmények
Intersect Rendezett eredmények Rendezetlen eredmények
Join Rendezett eredmények Rendezetlen eredmények
Last Megadott elem visszaadva Tetszőleges elem
LastOrDefault Megadott elem visszaadva Tetszőleges elem
LongCount Nem alkalmazható Nem alkalmazható
Min Nem alkalmazható Nem alkalmazható
OrderBy A sorrend átrendezése Új rendezett szakasz indítása
OrderByDescending A sorrend átrendezése Új rendezett szakasz indítása
Range Nem alkalmazható (az alapértelmezett érték ugyanaz, mint AsParallel a ) Nem alkalmazható
Repeat Nem alkalmazható (az alapértelmezett érték ugyanaz, mint AsParallela ) Nem alkalmazható
Reverse Megfordítja Nem tesz semmit
Select Rendezett eredmények Rendezetlen eredmények
Select (indexelt) Rendezett eredmények Rendezetlen eredmények.
SelectMany Rendezett eredmények. Rendezetlen eredmények
SelectMany (indexelt) Rendezett eredmények. Rendezetlen eredmények.
SequenceEqual Rendezett összehasonlítás Rendezetlen összehasonlítás
Single Nem alkalmazható Nem alkalmazható
SingleOrDefault Nem alkalmazható Nem alkalmazható
Skip Az első n elemek kihagyása Kihagyja az n elemeket
SkipWhile Rendezett eredmények. Nemdeterminista. A SkipWhile végrehajtása az aktuális tetszőleges sorrendben
Sum Nemdeterminista kimenet nem társító vagy nem kommutatív műveletekhez Nemdeterminista kimenet nem társító vagy nem kommutatív műveletekhez
Take Első n elemeket vesz fel Bármilyen n elemet átvesz
TakeWhile Rendezett eredmények Nemdeterminista. TakeWhile végrehajtása az aktuális tetszőleges sorrendben
ThenBy Kiegészítők OrderBy Kiegészítők OrderBy
ThenByDescending Kiegészítők OrderBy Kiegészítők OrderBy
ToArray Rendezett eredmények Rendezetlen eredmények
ToDictionary Nem alkalmazható Nem alkalmazható
ToList Rendezett eredmények Rendezetlen eredmények
ToLookup Rendezett eredmények Rendezetlen eredmények
Union Rendezett eredmények Rendezetlen eredmények
Where Rendezett eredmények Rendezetlen eredmények
Where (indexelt) Rendezett eredmények Rendezetlen eredmények
Zip Rendezett eredmények Rendezetlen eredmények

A rendezetlen eredmények nincsenek aktívan elfojtva; egyszerűen nincsenek speciális rendezési logikák alkalmazva rájuk. Bizonyos esetekben a rendezetlen lekérdezések megtarthatják a forrásütemezés sorrendjét. Az indexelt Select operátort használó lekérdezések esetében a PLINQ garantálja, hogy a kimeneti elemek az indexek növelésének sorrendjében jelennek meg, de nem garantálja, hogy mely indexek mely elemekhez lesznek hozzárendelve.

Lásd még