I was worried about C#'s speed when it deals with heavy calculations, when you need to use raw CPU power.
I always thought that C++ is much faster than C# when it comes to calculations. So I did some quick tests. The first test computes prime numbers < an integer n, the second test computes some pandigital numbers. The idea for second test comes from here: Pandigital Numbers
C# prime computation:
using System;
using System.Diagnostics;
class Program
{
static int primes(int n)
{
uint i, j;
int countprimes = 0;
for (i = 1; i <= n; i++)
{
bool isprime = true;
for (j = 2; j <= Math.Sqrt(i); j++)
if ((i % j) == 0)
{
isprime = false;
break;
}
if (isprime) countprimes++;
}
return countprimes;
}
static void Main(string[] args)
{
int n = int.Parse(Console.ReadLine());
Stopwatch sw = new Stopwatch();
sw.Start();
int res = primes(n);
sw.Stop();
Console.WriteLine("I found {0} prime numbers between 0 and {1} in {2} msecs.", res, n, sw.ElapsedMilliseconds);
Console.ReadKey();
}
}
C++ variant:
#include <iostream>
#include <ctime>
#include <cmath>
int primes(unsigned long n) {
unsigned long i, j;
int countprimes = 0;
for(i = 1; i <= n; i++) {
int isprime = 1;
for(j = 2; j < sqrt((float)i); j++)
if(!(i%j)) {
isprime = 0;
break;
}
countprimes+= isprime;
}
return countprimes;
}
int main() {
int n, res;
cin>>n;
unsigned int start = clock();
res = primes(n);
int tprime = clock() - start;
cout<<"\nI found "<<res<<" prime numbers between 1 and "<<n<<" in "<<tprime<<" msecs.";
return 0;
}
When I ran the test trying to find primes < than 100,000, C# variant finished in 0.409 seconds and C++ variant in 0.614 seconds. When I ran them for 1,000,000 C# finished in 6.039 seconds and C++ in about 12.987 seconds.
Pandigital test in C#:
using System;
using System.Diagnostics;
class Program
{
static bool IsPandigital(int n)
{
int digits = 0; int count = 0; int tmp;
for (; n > 0; n /= 10, ++count)
{
if ((tmp = digits) == (digits |= 1 << (n - ((n / 10) * 10) - 1)))
return false;
}
return digits == (1 << count) - 1;
}
static void Main()
{
int pans = 0;
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 1; i <= 123456789; i++)
{
if (IsPandigital(i))
{
pans++;
}
}
sw.Stop();
Console.WriteLine("{0}pcs, {1}ms", pans, sw.ElapsedMilliseconds);
Console.ReadKey();
}
}
Pandigital test in C++:
#include <iostream>
#include <ctime>
using namespace std;
int IsPandigital(int n)
{
int digits = 0; int count = 0; int tmp;
for (; n > 0; n /= 10, ++count)
{
if ((tmp = digits) == (digits |= 1 << (n - ((n / 10) * 10) - 1)))
return 0;
}
return digits == (1 << count) - 1;
}
int main() {
int pans = 0;
unsigned int start = clock();
for (int i = 1; i <= 123456789; i++)
{
if (IsPandigital(i))
{
pans++;
}
}
int ptime = clock() - start;
cout<<"\nPans:"<<pans<<" time:"<<ptime;
return 0;
}
C# variant runs in 29.906 seconds and C++ in about 36.298 seconds.
I didn't touch any compiler switches and both C# and C++ programs were compiled with debug options. Before I attempted to run the test I was worried that C# will lag well behind C++, but now it seems that there is a pretty big speed difference in C# favor.
Can anybody explain this? C# is jitted and C++ is compiled native so it's normal that a C++ will be faster than a C# variant.
Thanks for the answers!
I've redid all tests for the Release configuration.
First test (prime numbers)
C# (numbers < 100,0000): 0.189 seconds C++ (numbers < 100,0000): 0.036 seconds
C# (nummbers < 1,000,000): 5.300 seconds C++ (nummbers < 1,000,000): 1.166 seconds
Second test (pandigital numbers):
C#: 21.224 seconds C++: 4.104 seconds
So, everytthing have changed, now C++ is much faster. My mistake is that I've ran the test for Debug configuration. Can I see some speed improvement if I ran the C# executables through ngen?
The reason I tried to compare C# and C++ is because I know some basics of both and I wanted to learn an API dealing with GUI. I was thinking that WPF is nice so given that I'm targeting the desktop, I wanted to see if C# can deliver enough speed and performance when it comes to use sheer CPU power to compute various calculations (file archivers, cryptography, codecs etc). But it seems that sadly C# can't keep pace with C++ when it comes to speed.
So, I'm assuming I will be forever stuck with this question Tough question on WPF, Win32, MFC, and I'll newer find an suitable API.