public static void PLINQExample() { Console.WriteLine($"Poiščimo praštevila v veliki množici:"); // Praštevila iz množice si shranimo v drug seznam List <int> primes = new List <int>(); // Najprej preizkusimo običajni pristop Stopwatch sw = Stopwatch.StartNew(); DataForParallel.Instance().ForEach(i => { if (CommonFunctions.IsPrime(i)) { primes.Add(i); } }); Console.WriteLine($"Čas zaporednega iskanja: {sw.Elapsed.TotalSeconds}, našli smo {primes.Count} praštevil."); // Sedaj pa jih preverimo paralelno primes.Clear(); sw = Stopwatch.StartNew(); // Naš seznam prevedemo v instanco ParallelQuery<T> s klicem funkcije AsParallel. // Nato uporabimo funkcijo ForAll, ki naredi enako kot ForEach zgoraj, // le da uporabi več paralelnih niti. DataForParallel.Instance().AsParallel().ForAll(i => { if (CommonFunctions.IsPrime(i)) { // Ker vzporedno dodajamo elemente v seznam (niti si ga delijo), // ga moramo ob vsakem dodajanju 'zakleniti', // da ga ne uporabi hkrati druga nit in ne pride do manjkajočih vnosov lock (primes) { primes.Add(i); } } }); Console.WriteLine($"Čas vzporednega iskanja: {sw.Elapsed.TotalSeconds}, našli smo {primes.Count} praštevil."); // Če ne uporabimo 'lock', nam nekaj vnosov zmanjka primes.Clear(); sw = Stopwatch.StartNew(); DataForParallel.Instance().AsParallel().ForAll(i => { if (CommonFunctions.IsPrime(i)) { primes.Add(i); } }); Console.WriteLine($"Čas vzporednega iskanja brez lock-a: {sw.Elapsed.TotalSeconds}, našli smo {primes.Count} praštevil."); // Poleg metode ForAll imamo na voljo še nekaj drugih metod. Npr. Select, OrderBy itd. // V zgornjih primerih smo uporabili vsa jedra procesorja, kar ni vedno dobrodošlo. // Število uporabljenih jeder lahko tudi omejimo z metodo WithDegreeOfParallelism. // Preverimo paralelno samo s tremi jedri. for (int i = 1; i < Environment.ProcessorCount; i++) { primes.Clear(); sw = Stopwatch.StartNew(); DataForParallel.Instance().AsParallel() .WithDegreeOfParallelism(i) .ForAll(i => { if (CommonFunctions.IsPrime(i)) { // Ker vzoredno dodajamo elemente v seznam, // ga moramo ob vsakem dodajanju 'zakleniti', // da ga ne uporabi hkrati druga nit in ne pride do manjkajočih vnosov lock (primes) { primes.Add(i); } } }); Console.WriteLine($"Čas vzporednega iskanja z {i} jedri od {Environment.ProcessorCount}: {sw.Elapsed.TotalSeconds}, našli smo {primes.Count} praštevil."); } }