Created
September 23, 2011 10:00
-
-
Save dazfuller/1237064 to your computer and use it in GitHub Desktop.
Some examples using Parallelism in .NET 4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using System.Diagnostics; | |
namespace PLinqDemo | |
{ | |
class Demo | |
{ | |
private IEnumerable<int>_numRange = Enumerable.Range(1, 500); | |
public void RunDemo() | |
{ | |
Console.WriteLine("Running Demo"); | |
TaskDemo(); Console.WriteLine(); | |
ParallelForAllDemo(); Console.WriteLine(); | |
ParallelForEachDemo(); Console.WriteLine(); | |
SerialForEachDemo(); Console.WriteLine(); | |
ParallelLinqDemo(); Console.WriteLine(); | |
SerialLinqDemo(); Console.WriteLine(); | |
} | |
/// <summary> | |
/// Runs the demo methods | |
/// </summary> | |
private void TaskDemo() | |
{ | |
Task<int> t = new Task<int>(GuessNumber, 8861102); | |
Console.WriteLine("About to start task"); | |
t.Start(); | |
Console.WriteLine("Task has started"); | |
while (false == t.IsCompleted) | |
{ | |
Console.WriteLine("Waiting for result"); | |
Thread.Sleep(50); | |
} | |
Console.WriteLine("It took {0} attempt(s) to guess the number ", t.Result); | |
Console.WriteLine("Task completed"); | |
} | |
/// <summary> | |
/// Runs a Parallel.ForAll on the number collection, this should be the fastest | |
/// of all three for-each/all demos as there is no final aggregation | |
/// </summary> | |
private void ParallelForAllDemo() | |
{ | |
Stopwatch sw = new Stopwatch(); | |
sw.Start(); | |
_numRange.AsParallel().ForAll((n) => { Console.Write("{0} ", n); LongTask(); }); | |
sw.Stop(); | |
Console.WriteLine("\n\nRunning a parallel for-all loop took {0} milliseconds\n\n", sw.ElapsedMilliseconds); | |
} | |
/// <summary> | |
/// Runs a Parallel.ForEach on the number collection, this should be slower than | |
/// a for-all but faster than the serial version as the processing is happening | |
/// using all available cores. Note, on single core machines there should be | |
/// no difference in speed | |
/// </summary> | |
private void ParallelForEachDemo() | |
{ | |
Stopwatch sw = new Stopwatch(); | |
sw.Start(); | |
Parallel.ForEach(_numRange, (n) => { Console.Write("{0} ", n); LongTask(); }); | |
sw.Stop(); | |
Console.WriteLine("\n\nRunning a parallel for-each loop took {0} milliseconds\n\n", sw.ElapsedMilliseconds); | |
} | |
/// <summary> | |
/// Runs a standard foreach on the number collection, this should be the slowest | |
/// of all the for-each/all demos except on single-core, single-processor machines | |
/// </summary> | |
private void SerialForEachDemo() | |
{ | |
Stopwatch sw = new Stopwatch(); | |
sw.Start(); | |
foreach (int n in _numRange) | |
{ | |
Console.Write("{0} ", n); | |
LongTask(); | |
} | |
sw.Stop(); | |
Console.WriteLine("\n\nRunning a standard, serial for-each loop took {0} milliseconds", sw.ElapsedMilliseconds); | |
} | |
/// <summary> | |
/// This is an example of using Parallel LINQ, this should be slower or of equal | |
/// speed to the standard serial LINQ example as there is no processing involved in | |
/// selecting an element. If the "AsSequential" method is removed then this can be | |
/// slower as the items are not accessed in a sequential manner and so collection of | |
/// the values matching the criteria will be slower. Thread safety will also | |
/// provide a bottle neck | |
/// </summary> | |
private void ParallelLinqDemo() | |
{ | |
Console.WriteLine("Using PLINQ to determine the average of the values between 100 and 200"); | |
Stopwatch sw = new Stopwatch(); | |
sw.Start(); | |
double result = (from n in _numRange.AsParallel().AsSequential() | |
where n >= 300 && n <= 400 | |
select n).Average(); | |
sw.Stop(); | |
Console.WriteLine("Calculating the average value of {0} took {1} milliseconds", result, sw.ElapsedMilliseconds); | |
} | |
/// <summary> | |
/// An example of using LINQ to find all values matching a criteria from a collection | |
/// </summary> | |
private void SerialLinqDemo() | |
{ | |
Console.WriteLine("Using LINQ to determine the average of the values between 300 and 400"); | |
Stopwatch sw = new Stopwatch(); | |
sw.Start(); | |
double result = (from n in _numRange | |
where n >= 300 && n <= 400 | |
select n).Average(); | |
sw.Stop(); | |
Console.WriteLine("Calculating the average value of {0} took {1} milliseconds", result, sw.ElapsedMilliseconds); | |
} | |
/// <summary> | |
/// Method to perform a task | |
/// </summary> | |
/// <param name="o">Object state</param> | |
/// <returns>Number of guesses taken</returns> | |
public int GuessNumber(object o) | |
{ | |
int value = Convert.ToInt32(o); | |
int upperBound = value * 2; | |
Random rand = new Random(); | |
int count = 1; | |
while (rand.Next(upperBound) != value) | |
{ | |
count++; | |
} | |
return count; | |
} | |
/// <summary> | |
/// Runs a process intensive task numerous times to provide slow down the thread. A | |
/// Thread.Sleep call could be used instead but will not show much difference in the | |
/// task manager. Using this method the task manager can be used to show how the load | |
/// is being split between cores and processors. | |
/// </summary> | |
private void LongTask() | |
{ | |
for (int i = 0; i < 10000; i++) | |
{ | |
var ms = DateTime.Now.Millisecond; | |
} | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
// Create a new Demo object and run it's examples | |
Demo d = new Demo(); | |
d.RunDemo(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment