C# Console Application, .NET Framework 2.0
Program.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace PerformanceTester
{
class Program
{
private const int NUM = 5000000;
static void Main(string[] args)
{
for (int i = 0; i < 3; i++)
{
DateTime start;
TimeSpan span;
start = DateTime.Now;
SingleThreaded();
span = DateTime.Now.Subtract(start);
Console.WriteLine(
String.Format("\tSingle Threaded : {0} ms",
span.TotalMilliseconds));
start = DateTime.Now;
DoubleThreaded();
span = DateTime.Now.Subtract(start);
Console.WriteLine(
String.Format("\tDouble Threaded : {0} ms",
span.TotalMilliseconds));
}
Console.Read();
}
private static void SingleThreaded()
{
PrimeGenerator generator = new PrimeGenerator();
List<int> results = new List<int>();
generator.AddPrimes(results, 1, NUM);
}
private static void DoubleThreaded()
{
List<int> results = new List<int>();
Thread t1 = new Thread(delegate()
{
PrimeGenerator generator =
new PrimeGenerator();
generator.AddPrimes(results,1,NUM/2);
});
Thread t2 = new Thread(delegate()
{
PrimeGenerator generator =
new PrimeGenerator();
generator.AddPrimes(results,NUM/2+1,NUM);
});
t1.Start(); t2.Start();
t1.Join(); t2.Join();
}
}
}
PrimeGenerator.cs
This program will search for all primes between 1 and 5000000 inclusive. It works in two mode, single threaded and double threaded. The search range is divided into two parts in double threaded mode, 1 - 2500000 and 2500001 - 5000000 (we can obviously see that the work load of the second range is bigger than the first one but since this is informal experiment so I did not care about this point :P). The program also record running times for each mode and print them on the screen.
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace PerformanceTester
{
class PrimeGenerator
{
private bool IsPrime(int n)
{
if (n <= 1)
return false;
else if (n <= 3)
return true;
else if (n % 2 == 0)
return false;
else
{
int bound = Convert.ToInt32(Math.Ceiling(Math.Sqrt(n)));
for (int i = 3; i <= bound; i++)
{
if (n % i == 0)
return false;
}
return true;
}
}
public void AddPrimes(List<int> list,int lowerBound,int upperBound)
{
for (int number = lowerBound; number < upperBound; number++)
{
if(IsPrime(number))
lock (list)
{
list.Add(number);
}
}
}
}
}
Here are the results:
Running on my IBM R52 - Intel(R) Pentium(R) M 1.60 GHz
(Single core)
Single Threaded : 11687.5 ms
Double Threaded : 12875 ms
Single Threaded : 12812.5 ms
Double Threaded : 12953.125 ms
Single Threaded : 12000 ms
Double Threaded : 11703.125 ms
Running on my mom's IBM R60 - Intel(R) Core(TM)2 CPU 15500 @ 1.66GHz
(Double core)
Single Threaded : 9171.875 ms
Double Threaded : 5625 ms
Single Threaded : 9109.375 ms
Double Threaded : 5625 ms
Single Threaded : 9109.375 ms
Double Threaded : 5609.375 ms
For single core, the running time is practically the same for each mode. While for double core, double threaded mode gives noticeably better running time.
So, to take advantage of new duo core processors nowadays, considers building your program to support multi threaded mode.