Reputation: 3265
Here are two code parts in c++ and c# doing absolutely the same thing:
#include <stdio.h>
int main(int argc, char *argv[]) {
char p[1000000];
unsigned int i,j;
unsigned long long s=0;
for(i=2;i<1000000;i++) p[i]=1;
for(i=2;i<500000;) {
for(j=2*i;j<1000000;j+=i) p[j]=0;
for(i++;!p[i];i++);
}
for(i=3,s=2;i<1000000;i+=2) if(p[i]) s+=i;
printf ("%lld\n",s);
return 0;
}
time: 0.01s memmory: 2576 kB
using System;
namespace ConsoleApplication4
{
internal class Program
{
private static void Main(string[] args)
{
var p = new byte[1000000];
ulong i, j;
double s = 0;
for(i=2;i<1000000;i++)
p[i]=1;
for(i=2;i<500000;)
{
for(j=2*i;j<1000000;j+=i)
p[j]=0;
for(i++;p[i]==0;i++);
}
for(i=3,s=2;i<1000000;i+=2)
if(p[i]!=0) s+=i;
Console.WriteLine(s);
}
}
}
time: 0.05s mem: 38288 kB
How can I improve the C# code to prove that C# can be as fast as C++ to my colleague?
As you can see the C# execution time is 5 time larger, and the memory consumption is 15 times larger.
Upvotes: 5
Views: 4466
Reputation: 3362
Just a note to your timing. Its not shown, how did you measure the execution times. One can expect a reasonable overhead for .NET applications on startup. So if you are about the execution time of the loops only, you should run the inner loops several (many) times, skip the 1..2 first iterations, measure the other iterations and compute the average.
I would expect the results be more similar than. However, as always when targeting 'peak performance' - precautions regarding the memory management are important. Here, it probably would be sufficient to prevent from 'new' inside the measurement functions. Reuse the p[] in each iteration.
Upvotes: 3
Reputation: 31845
Go "unsafe" (unmanaged) for that... every time you're doing someSortOfArray[i]
, the .NET framework is doing all kinds of neat-o things (such as out of bounds checking) which take up time.
That's really the whole point of going unmanaged (and then using pointers and doing myPointer++).
Just to clarify, if you go unmanaged and then still do a for-loop
and do someArray[i]
, you've saved nothing.
Another S.O. question that may help you: True Unsafe Code Performance
By the way, I'm not saying to do this all the time, but rather as an answer for THIS specific question only.
Upvotes: 6
Reputation: 247979
How can I improve the C# code to prove that C# can be as fast as C++ to my colleague?
You can't. There are legitimate areas where C++ is fundamentally faster than C#. But there are also areas where C# code will perform better than the equivalent C++ code. They're different languages with different strengths and weaknesses.
But as a programmer, you really ought to base your decisions in logic.
Logic dictates that you should gather information first, and then decide based on that.
You, on the contrary, made the decision first, and then looked for information to support it. That may work if you're a politician, but it's not a good way to write software.
Don't go hunting for proof that C# is faster than C++. Instead, examine which option is faster in your case.
In any case, if you want to prove that X can be as fast as Y, you have to do it the usual way: make X as fast as Y. And as always, when doing performance tuning, a profiler is your best friend. Find out exactly where the additional time is being spent, and then figure out how to eliminate it.
Memory usage is a lost cause though. .NET simply uses more memory, for several reasons:
Upvotes: 6
Reputation: 54242
The memory usage may be related to garbage collection. In Java, memory usage is intentionally high -- garbage collection only happens when you need more memory. This is for speed reasons, so it would make sense that C# does the same thing. You shouldn't do this in release code, but to show much memory you're actually using, you can call GC.Collect()
before measuring memory usage. Do you really care how much memory it's using though? It seems like speed in more important. And if you have memory limits, you can probably set the amount of memory that your program will use before garbage collecting.
Upvotes: 1
Reputation: 1038820
Compile and run in Release mode. I get exactly 0.01s from the C# version when built and run in Release mode. As far as memory consumption is concerned you are comparing apples to oranges. A managed environment will consume more memory as it is hosting the CLR and the Garbage Collector which don't come without cost.
Upvotes: 10