Hi guys,
In my article, I want to compare the speed of sequential processing to parallel processing in various conditions, so in one example, I want to convert the following sequential command to parallel, but after converting it to parallel, it seems that the loop is not repeated for the specified number of times. It may be necessary to use Concurrent Collection or a lock
statement, but this usually reduces the speed of parallel processing compared to sequential processing.
So I want an example (preferably a simple example) for my article that compares for
and Parallel.ForEach
. This example should have the following features:
• The execution of Parallel.ForEach
block codes should be faster than the execution of ForEach
block codes.
• Using a flag, a variable, or other mechanisms, ensure that the Parallel.ForEach
loop is executed the predefined number of times.
Something like the following code (Parallel.For vs for
loop):
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp
{
class Program
{
const int LOOP_COUNT = 900000;
static long Calcute()
{
int Total = 0;
for (int i = 0; i < 10000; i++) // add more iteration to make parallel faster than sequential
{
Total += 20 * i;
}
return Total;
}
static void SequentialCalculate()
{
var Counter = 0;
long Total = 0;
Stopwatch SW = new Stopwatch();
SW.Start();
for (int i = 0; i < LOOP_COUNT; i++)
{
Total = Calcute();
++Counter;
}
SW.Stop();
Console.WriteLine("Sequential total seconds: " + SW.Elapsed.TotalSeconds + ", Counter: " + Counter + ", Total: " + Total);
}
static void ParallelCalculate()
{
var Counter = 0;
long Total = 0;
Stopwatch SW = new Stopwatch();
SW.Start();
Parallel.For(0, LOOP_COUNT, i =>
{
Total = Calcute();
Interlocked.Add(ref Counter, 1);
});
SW.Stop();
Console.WriteLine("Parallel total seconds: " + SW.Elapsed.TotalSeconds + ", Counter: " + Counter + ", Total: " + Total);
}
static void Main(string[] args)
{
Console.ReadKey();
SequentialCalculate();
ParallelCalculate();
Console.ReadKey();
}
}
}
Result (by Intel Core i5-2430M
, no debug mode):
I tried this too but didn't get a proper result:
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Threading.Tasks;
namespace ConsoleApp
{
class Program
{
const long Count = 50000;
static long[] Numbers = new long[Count];
static long Calculate()
{
long Total = 0;
foreach (long Num in Numbers)
{
Total += Num;
}
return Total;
}
static void SequentialCalculate()
{
long Total = 0;
Stopwatch SW = new Stopwatch();
SW.Start();
foreach (long N in Numbers)
{
Total += N * Calculate();
}
SW.Stop();
Console.WriteLine("Sequential total seconds: " + SW.Elapsed.TotalSeconds + ", Total: " + Total);
}
static void ParallelCalculate()
{
long Total = 0;
Stopwatch SW = new Stopwatch();
SW.Start();
Parallel.ForEach((Partitioner.Create(0, Numbers.Length)), range =>
{
for (long N = range.Item1; N < range.Item2; N++)
{
Total += N * Calculate();
}
});
SW.Stop();
Console.WriteLine("Parallel total seconds: " + SW.Elapsed.TotalSeconds + ", Total: " + Total);
}
static void Main(string[] args)
{
for (long i = 0; i < Count; i++)
{
Numbers[i] = i;
}
Console.WriteLine("Ready to calculate");
Console.ReadKey();
SequentialCalculate();
ParallelCalculate();
Console.ReadKey();
}
}
}
Result (by Intel Core i5-2430M
, no debug mode):
I use the following tools:
• .NET Framework 4.5
• Console app
• Windows 7
Thank you for your time.