Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
V PLINQ je cílem maximalizovat výkon při zachování správnosti. Dotaz by se měl spustit co nejrychleji, ale přesto vytvořit správné výsledky. V některých případech je správnost závislá na zachování pořadí prvotní sekvence; nicméně řazení může být výpočetně nákladné. Ve výchozím nastavení proto PLINQ nezachová pořadí zdrojové sekvence. V tomto ohledu PLINQ připomíná LINQ to SQL, ale je na rozdíl od LINQ to Objects, což zachovává pořadí.
Chcete-li přepsat výchozí chování, můžete zapnout zachování pořadí pomocí AsOrdered operátoru ve zdrojové sekvenci. Uchovávání objednávek pak můžete vypnout později v dotazu pomocí AsUnordered metody. U obou metod se dotaz zpracuje na základě heuristiky, které určují, jestli se má dotaz spustit jako paralelní nebo sekvenční. Další informace naleznete v tématu Principy zrychlení v PLINQ.
Následující příklad ukazuje neuspořádaný paralelní dotaz, který filtruje pro všechny prvky, které odpovídají podmínce, aniž byste se pokusili výsledky uspořádat jakýmkoli způsobem.
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)
Tento dotaz nemusí nutně vytvořit prvních 1 000 měst ve zdrojové sekvenci, která splňují podmínku, ale spíše některé sady 1 000 měst, která splňují podmínku. Operátory dotazu PLINQ rozdělují zdrojová sekvence do několika dílčích sekvencí, které se zpracovávají jako souběžné úlohy. Pokud není zadáno zachování pořadí, výsledky z každé části jsou předány do další fáze dotazu v libovolném pořadí. Partice může také poskytnout podmnožinu svých výsledků, než bude pokračovat ve zpracování zbývajících prvků. Výsledné pořadí se může pokaždé lišit. Aplikace to nemůže řídit, protože závisí na tom, jak operační systém naplánuje vlákna.
Následující příklad přepíše výchozí chování pomocí operátoru AsOrdered ve zdrojové sekvenci. Tím zajistíte, že Take metoda vrátí prvních 1 000 měst ve zdrojové sekvenci, která splňují podmínku.
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)
Tento dotaz se však pravděpodobně nespustí tak rychle jako neuspořádaná verze, protože sleduje původní řazení v rámci oddílů a při sloučení zajišťuje, aby řazení bylo konzistentní. Proto doporučujeme, abyste ho používali AsOrdered jenom v případě potřeby a pouze pro ty části dotazu, které ho vyžadují. Pokud už se zachování objednávky nevyžaduje, použijte AsUnordered ji k vypnutí. Následující příklad toho dosáhne tak, že vytvoří dva dotazy.
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
Všimněte si, že PLINQ zachovává pořadí sekvence vytvořené operátory, které ukládají pořadí, pro zbytek dotazu. Jinými slovy, s operátory, jako jsou OrderBy a ThenBy, se zachází, jako by následoval jejich volání AsOrdered.
Operátory dotazů a řazení
Následující operátory dotazu zavádějí zachování pořadí do všech následných operací v dotazu, nebo dokud AsUnordered se nevolá:
Následující operátory dotazů PLINQ můžou v některých případech vyžadovat seřazené zdrojové sekvence, aby vznikly správné výsledky:
Některé operátory dotazů PLINQ se chovají odlišně v závislosti na tom, jestli je jejich zdrojová sekvence seřazená nebo neuspořádaná. Následující tabulka uvádí tyto operátory.
| Operátor | Výsledek při seřazení zdrojové sekvence | Výsledek v případech, kdy je pořadí zdroje neuspořádané |
|---|---|---|
| Aggregate | Nedeterministický výstup pro nonassociativní nebo nekomutativní operace | Nedeterministický výstup pro nonassociativní nebo nekomutativní operace |
| All | Není relevantní | Není relevantní |
| Any | Není relevantní | Není relevantní |
| AsEnumerable | Není relevantní | Není relevantní |
| Average | Nedeterministický výstup pro nonassociativní nebo nekomutativní operace | Nedeterministický výstup pro nonassociativní nebo nekomutativní operace |
| Cast | Seřazené výsledky | Neuspořádané výsledky |
| Concat | Seřazené výsledky | Neuspořádané výsledky |
| Count | Není relevantní | Není relevantní |
| DefaultIfEmpty | Není relevantní | Není relevantní |
| Distinct | Seřazené výsledky | Neuspořádané výsledky |
| ElementAt | Vraťte zadaný prvek | Libovolný prvek |
| ElementAtOrDefault | Vraťte zadaný prvek | Libovolný prvek |
| Except | Neuspořádané výsledky | Neuspořádané výsledky |
| First | Vraťte zadaný prvek | Libovolný prvek |
| FirstOrDefault | Vraťte zadaný prvek | Libovolný prvek |
| ForAll | Vykonává se paralelně nedeterministicky. | Vykonává se paralelně nedeterministicky. |
| GroupBy | Seřazené výsledky | Neuspořádané výsledky |
| GroupJoin | Seřazené výsledky | Neuspořádané výsledky |
| Intersect | Seřazené výsledky | Neuspořádané výsledky |
| Join | Seřazené výsledky | Neuspořádané výsledky |
| Last | Vraťte zadaný prvek | Libovolný prvek |
| LastOrDefault | Vraťte zadaný prvek | Libovolný prvek |
| LongCount | Není relevantní | Není relevantní |
| Min | Není relevantní | Není relevantní |
| OrderBy | Přeuspořádá pořadí. | Spustí novou seřazenou sekci. |
| OrderByDescending | Přeuspořádá pořadí. | Spustí novou seřazenou sekci. |
| Range | Nepoužitelné (stejné výchozí jako AsParallel ) | Není relevantní |
| Repeat | Nepoužitelné (stejné výchozí jako AsParallel) | Není relevantní |
| Reverse | Otočí zpět | Nedělá nic |
| Select | Seřazené výsledky | Neuspořádané výsledky |
| Select (indexováno) | Seřazené výsledky | Neuspořádané výsledky |
| SelectMany | Seřazené výsledky | Neuspořádané výsledky |
| SelectMany (indexováno) | Seřazené výsledky | Neuspořádané výsledky |
| SequenceEqual | Uspořádané srovnání | Neuspořádané porovnání |
| Single | Není relevantní | Není relevantní |
| SingleOrDefault | Není relevantní | Není relevantní |
| Skip | Přeskočí první n prvků. | Přeskočí všechny n elementy. |
| SkipWhile | Seřazené výsledky | Nedeterministické. Provede Skip While u aktuálního libovolného pořadí. |
| Sum | Nedeterministický výstup pro nonassociativní nebo nekomutativní operace | Nedeterministický výstup pro nonassociativní nebo nekomutativní operace |
| Take | Vezme první n prvky. |
Přebírá všechny n prvky. |
| TakeWhile | Seřazené výsledky | Nedeterministické. Provede metodu TakeWhile na aktuální libovolné pořadí. |
| ThenBy | Doplňky OrderBy |
Doplňky OrderBy |
| ThenByDescending | Doplňky OrderBy |
Doplňky OrderBy |
| ToArray | Seřazené výsledky | Neuspořádané výsledky |
| ToDictionary | Není relevantní | Není relevantní |
| ToList | Seřazené výsledky | Neuspořádané výsledky |
| ToLookup | Seřazené výsledky | Neuspořádané výsledky |
| Union | Seřazené výsledky | Neuspořádané výsledky |
| Where | Seřazené výsledky | Neuspořádané výsledky |
| Where (indexováno) | Seřazené výsledky | Neuspořádané výsledky |
| Zip | Seřazené výsledky | Neuspořádané výsledky |
Neuspořádané výsledky nejsou aktivně prohazovány; prostě nemají žádnou speciální logiku řazení, která by se na ně použila. V některých případech může neuspořádaný dotaz zachovat pořadí zdrojové sekvence. U dotazů, které používají indexovaný operátor Select, PLINQ zaručuje, že výstupní prvky budou přijít v pořadí zvýšení indexů, ale neposkytuje žádné záruky, které indexy budou přiřazeny k jakým prvkům.
Viz také
- Parallel LINQ (PLINQ)
- Paralelní programování