Why is C# 450% slower than C++ on nested loops ??

P

Peter Olcott

Ignacio Machin ( .NET/ C# MVP ) said:
Post the link for the patent
It has just been approved December 13, 2005. I am taking my maximum time to
decide whether or not to file a divisional, a continuation, or continuation in
part. This is three months. The patent office then takes about another three
months. Then it will be posted to their website. Sometime around June 13, 2006.
 
P

Peter Olcott

Marcus Cuda said:
my apologizes. I didn't see the code listed on the site you gave (I do now),
so I grabbed the code from http://dada.perl.it/shootout - which was linked
from your url.

I am quite new to .NET, I would be interested in seeing the CIL generated from
both the C# and the C++. I would also like to see if the native C++ is much
different from the managed C++ in its benchmark performance. Thanks.
 
C

Cecil

Um, why are we arguing over this?
Unmanaged C++ is going to outperform pretty much anything. If you need
that speed & you're not getting it w/ .NET then use C++. No biggy. I
love C++. Wouldn't want to write video games in anything else. But I
wouldn't wanna write Web Apps or Windows Apps in it anymore either. At
least not Win32 ones. It's just too tedious and the performance of .net
is exceptable for what I'm doing.

Why don't you benchmark your secret code and determine what gives you
the most positives and least negatives in terms of speed,
maintainability, deployment, etc. I don't think we can be of much help
since we're not in on the particulars of your code.

It's hard to find an area in CS that has one always best solution I'm
afraid. Since only you will be able to know all the specifics of what
you're accomplishing only you can find your answer.
 
W

Willy Denoyette [MVP]

Cecil said:
I'm not a compiler authority, but I did believe it common knowledge
that the C++ compiler was the best of the bunch in terms on speed. The
engineers behind it have said that even managed code done in C++ will
outperform the other languages.
Both managed C++ and C# compile to IL which translates to machine code by
exactly the same JIT compiler. Only difference is that the managed C++
compiler is less time constrained when optimizing the IL, but even with this
slight advantage the differences are minimal and not always in favor of C++,
simply because:
the compiler teams deliver well optimized IL, but they won't spend much time
trying to optimize something that better can be left to the JIT
compiler/optimizer.
I doubt 450% is likely though. It sounds to me like you may be
comparing binary code to code that has yet to be compiled which
obviously will run signifigantly slower in most instances.

Not at all, both are compiled binary code.

Willy.
 
W

Willy Denoyette [MVP]

Peter Olcott said:
http://www.tommti-systems.de/go.htm...ain-Dateien/reviews/languages/benchmarks.html
The above link shows that C# is 450% slower on something as simple as a
nested loop. Is this because .NET is inherently slower or does the C#
compiler merely produce code that is not as well optimized as the C++
compiler?

I know why but I don't care, these benchmarks are clueless and they are
broken, compile the C# code with /checked+ (check overflow on) and watch the
exceptions getting thrown on you.

Willy.
 
J

Joanna Carter [TeamB]

"Willy Denoyette [MVP]" <[email protected]> a écrit dans le message
de [email protected]...

| I know why but I don't care, these benchmarks are clueless and they are
| broken, compile the C# code with /checked+ (check overflow on) and watch
the
| exceptions getting thrown on you.

Can I ask whether these benchmarks were taken from C# code on first run
(including JITting) or after it has been JITted ? It is only sensible to
exclude the JIT process if you are comparing execution times as, after the
first execution, times get a great deal faster due to the code now being
natively compiled.

Joanna
 
F

Fabio Cannizzo

It would seem to me that non managed code will be eventually phased out,
at least on the MS Windows platform.

I am sure you have your reasons for rejecting the idea of interop code.
However, ifwhat you mention above is your only concern, you may be right,
but I would place a very big bet you are pretty safe at least for the next
10 years.
Actually, some mathematichal intensive software is still maintained in
Fortran and has not even migrated yet to C. So I guess it may take even
longer, say another 30 years?
I believe native code is there to stay for the moment, and by the time it
become obsolete I am pretty sure you'll have had the time to complete your
patent and may be rewrite your code in same more advanced and faster
technology.
On a separate subject, I used to write ASM inline in my C++. VC4could easily
be beaten , but VC6... that's another story! I suppose DotNet will undergo
the same evolution.

Good luck
F
 
P

Peter Olcott

Joanna Carter said:
"Willy Denoyette [MVP]" <[email protected]> a écrit dans le message
de [email protected]...

| I know why but I don't care, these benchmarks are clueless and they are
| broken, compile the C# code with /checked+ (check overflow on) and watch
the
| exceptions getting thrown on you.

Can I ask whether these benchmarks were taken from C# code on first run
(including JITting) or after it has been JITted ? It is only sensible to
exclude the JIT process if you are comparing execution times as, after the
first execution, times get a great deal faster due to the code now being
natively compiled.

It must have been after the JIT, because C# beat C++ on some things, just not
the nested loops. The author of the link would know relatively obvious things
such as this.
 
P

Peter Olcott

Fabio Cannizzo said:
I am sure you have your reasons for rejecting the idea of interop code.
However, ifwhat you mention above is your only concern, you may be right, but
I would place a very big bet you are pretty safe at least for the next 10
years.
Actually, some mathematichal intensive software is still maintained in Fortran
and has not even migrated yet to C. So I guess it may take even longer, say
another 30 years?
I believe native code is there to stay for the moment, and by the time it
become obsolete I am pretty sure you'll have had the time to complete your
patent and may be rewrite your code in same more advanced and faster
technology.

The patent is completed. I originally filed the provisional patent in August
2001. The regular patent was filed a year later. In the worst case I will have
to digress to unmanaged code. In theory there is no reason why this should be
necessary.
 
W

Willy Denoyette [MVP]

Joanna Carter said:
"Willy Denoyette [MVP]" <[email protected]> a écrit dans le
message
de [email protected]...

| I know why but I don't care, these benchmarks are clueless and they are
| broken, compile the C# code with /checked+ (check overflow on) and watch
the
| exceptions getting thrown on you.

Can I ask whether these benchmarks were taken from C# code on first run
(including JITting) or after it has been JITted ? It is only sensible to
exclude the JIT process if you are comparing execution times as, after the
first execution, times get a great deal faster due to the code now being
natively compiled.

Joanna

The timer is started when the function runs so after it's been compiled
(compiling the static di-unction takes less than a millisec. anyway).

Willy.
 
W

Willy Denoyette [MVP]

Peter Olcott said:
http://www.tommti-systems.de/go.htm...ain-Dateien/reviews/languages/benchmarks.html
The above link shows that C# is 450% slower on something as simple as a
nested loop. Is this because .NET is inherently slower or does the C#
compiler merely produce code that is not as well optimized as the C++
compiler?

Argggg... broken benchmarks published by people who have no clue what they
are talking about, sorry.
Just to mention what's broken in the function that's 450% slower here is the
correct code for C#.

//x was an int type, but should be a long, else the result x will overflow
several hundred times (and be incorrect), and negatively impacting the
execution time.


int a = 0, b = 0, c = 0, d= 0, e = 0, f = 0;
long x=0; // see note above
startTime = DateTime.Now;
for (a=0; a!=n; a++)
for (b=0; b!=n; b++)
for (c=0; c!=n; c++)
for (d=0; d!=n; d++)
for (e=0; e!=n; e++)
for (f=0; f!=n; f++)
x+=a+b+c+d+e+f;

[1] This is the correct code which is still ~50% slower than the (corrected)
native C++ code ( __int64 x=0;).

Herewith are the timings measured on my system.

1) C# with /o+
Nested Loop elapsed time: 10015 ms - 479232000000

2) VC++ with /O2 /EHsc (native code)
Nested Loop elapsed time: 6171 ms 479232000000

Note that this is a sample where the native C++ compiler optimizer does a
better job than C# and the JIT compiler/optimizer.

3) VC++ with /O2 /clr (managed code, unverifiable!!!)
Nested Loop elapsed time: 6406 ms 479232000000
In this particular case, the C++/CLI compiler optimizer does a better job
than C# when generating the IL, at the cost of generating unverifiable
code!!.

3) And here to please you all is the result of the same function compiled to
safe IL

// function slightly adapted to make it possible to compile with /clr:safe
(verifiable) code
static void nl(int n) {

int a, b, c, d, e, f;
__int64 x = 0;

Stopwatch^ stopWatch = gcnew Stopwatch;
stopWatch->Start();

for (a=0; a<n; a++)
for (b=0; b<n; b++)
for (c=0; c<n; c++)
for (d=0; d<n; d++)
for (e=0; e<n; e++)
for (f=0; f<n; f++)
x+=a+b+c+d+e+f;
stopWatch->Stop();
TimeSpan ts = stopWatch->Elapsed;

System::Console::WriteLine("Nested Loop elapsed time: {0} sec.{1} msec.
{2}\n", ts.Seconds, ts.Milliseconds, x);
}

Nested Loop elapsed time: 12 sec.812 msec. 479232000000

Notice the result is slightly slower (dispite the O2 optimizing flag) than
the C# code, this is because the IL is constrained by the verifier (for both
C# and C++/CLI in safe mode). So here C# emits slightly better IL.

Willy.
 
M

Mark White

Awesome write-up! Thanks.

Is the C# code in debug or release mode?

Willy Denoyette said:
Peter Olcott said:
http://www.tommti-systems.de/go.htm...ain-Dateien/reviews/languages/benchmarks.html
The above link shows that C# is 450% slower on something as simple as a
nested loop. Is this because .NET is inherently slower or does the C#
compiler merely produce code that is not as well optimized as the C++
compiler?

Argggg... broken benchmarks published by people who have no clue what they
are talking about, sorry.
Just to mention what's broken in the function that's 450% slower here is the
correct code for C#.

//x was an int type, but should be a long, else the result x will overflow
several hundred times (and be incorrect), and negatively impacting the
execution time.


int a = 0, b = 0, c = 0, d= 0, e = 0, f = 0;
long x=0; // see note above
startTime = DateTime.Now;
for (a=0; a!=n; a++)
for (b=0; b!=n; b++)
for (c=0; c!=n; c++)
for (d=0; d!=n; d++)
for (e=0; e!=n; e++)
for (f=0; f!=n; f++)
x+=a+b+c+d+e+f;

[1] This is the correct code which is still ~50% slower than the (corrected)
native C++ code ( __int64 x=0;).

Herewith are the timings measured on my system.

1) C# with /o+
Nested Loop elapsed time: 10015 ms - 479232000000

2) VC++ with /O2 /EHsc (native code)
Nested Loop elapsed time: 6171 ms 479232000000

Note that this is a sample where the native C++ compiler optimizer does a
better job than C# and the JIT compiler/optimizer.

3) VC++ with /O2 /clr (managed code, unverifiable!!!)
Nested Loop elapsed time: 6406 ms 479232000000
In this particular case, the C++/CLI compiler optimizer does a better job
than C# when generating the IL, at the cost of generating unverifiable
code!!.

3) And here to please you all is the result of the same function compiled to
safe IL

// function slightly adapted to make it possible to compile with /clr:safe
(verifiable) code
static void nl(int n) {

int a, b, c, d, e, f;
__int64 x = 0;

Stopwatch^ stopWatch = gcnew Stopwatch;
stopWatch->Start();

for (a=0; a<n; a++)
for (b=0; b<n; b++)
for (c=0; c<n; c++)
for (d=0; d<n; d++)
for (e=0; e<n; e++)
for (f=0; f<n; f++)
x+=a+b+c+d+e+f;
stopWatch->Stop();
TimeSpan ts = stopWatch->Elapsed;

System::Console::WriteLine("Nested Loop elapsed time: {0} sec.{1} msec.
{2}\n", ts.Seconds, ts.Milliseconds, x);
}

Nested Loop elapsed time: 12 sec.812 msec. 479232000000

Notice the result is slightly slower (dispite the O2 optimizing flag) than
the C# code, this is because the IL is constrained by the verifier (for both
C# and C++/CLI in safe mode). So here C# emits slightly better IL.

Willy.
 
W

Willy Denoyette [MVP]

Mark White said:
Awesome write-up! Thanks.

Is the C# code in debug or release mode?

Optimized code see:

1) C# with /o+

This to be on par with the /O2 optimizing flag used to compile the C++ code.
Debug mode is obviously slower :)

Willy.
 
P

Peter Olcott

Willy Denoyette said:
Peter Olcott said:
http://www.tommti-systems.de/go.htm...ain-Dateien/reviews/languages/benchmarks.html
The above link shows that C# is 450% slower on something as simple as a
nested loop. Is this because .NET is inherently slower or does the C#
compiler merely produce code that is not as well optimized as the C++
compiler?

Argggg... broken benchmarks published by people who have no clue what they are
talking about, sorry.
Just to mention what's broken in the function that's 450% slower here is the
correct code for C#.

//x was an int type, but should be a long, else the result x will overflow
several hundred times (and be incorrect), and negatively impacting the
execution time.


int a = 0, b = 0, c = 0, d= 0, e = 0, f = 0;
long x=0; // see note above
startTime = DateTime.Now;
for (a=0; a!=n; a++)
for (b=0; b!=n; b++)
for (c=0; c!=n; c++)
for (d=0; d!=n; d++)
for (e=0; e!=n; e++)
for (f=0; f!=n; f++)
x+=a+b+c+d+e+f;

[1] This is the correct code which is still ~50% slower than the (corrected)
native C++ code ( __int64 x=0;).

Herewith are the timings measured on my system.

1) C# with /o+
Nested Loop elapsed time: 10015 ms - 479232000000

2) VC++ with /O2 /EHsc (native code)
Nested Loop elapsed time: 6171 ms 479232000000

Note that this is a sample where the native C++ compiler optimizer does a
better job than C# and the JIT compiler/optimizer.

3) VC++ with /O2 /clr (managed code, unverifiable!!!)
Nested Loop elapsed time: 6406 ms 479232000000
In this particular case, the C++/CLI compiler optimizer does a better job than
C# when generating the IL, at the cost of generating unverifiable code!!.

So the C++ compiler produces comparable speed for both managed and unmanaged
code. Whatever verifiable means. In software engineering it meant mathematical
proof of correctness.
 
P

Peter Olcott

Willy Denoyette said:
Argggg... broken benchmarks published by people who have no clue what they are
talking about, sorry.

What is wrong with the benchmark?
Just to mention what's broken in the function that's 450% slower here is the
correct code for C#.

//x was an int type, but should be a long, else the result x will overflow
several hundred times (and be incorrect), and negatively impacting the
execution time.


int a = 0, b = 0, c = 0, d= 0, e = 0, f = 0;
long x=0; // see note above
startTime = DateTime.Now;
for (a=0; a!=n; a++)
for (b=0; b!=n; b++)
for (c=0; c!=n; c++)
for (d=0; d!=n; d++)
for (e=0; e!=n; e++)
for (f=0; f!=n; f++)
x+=a+b+c+d+e+f;

[1] This is the correct code which is still ~50% slower than the (corrected)
native C++ code ( __int64 x=0;).

Herewith are the timings measured on my system.

1) C# with /o+
Nested Loop elapsed time: 10015 ms - 479232000000

2) VC++ with /O2 /EHsc (native code)
Nested Loop elapsed time: 6171 ms 479232000000

Note that this is a sample where the native C++ compiler optimizer does a
better job than C# and the JIT compiler/optimizer.

3) VC++ with /O2 /clr (managed code, unverifiable!!!)
Nested Loop elapsed time: 6406 ms 479232000000
In this particular case, the C++/CLI compiler optimizer does a better job than
C# when generating the IL, at the cost of generating unverifiable code!!.

3) And here to please you all is the result of the same function compiled to
safe IL

// function slightly adapted to make it possible to compile with /clr:safe
(verifiable) code
static void nl(int n) {

int a, b, c, d, e, f;
__int64 x = 0;

Stopwatch^ stopWatch = gcnew Stopwatch;
stopWatch->Start();

for (a=0; a<n; a++)
for (b=0; b<n; b++)
for (c=0; c<n; c++)
for (d=0; d<n; d++)
for (e=0; e<n; e++)
for (f=0; f<n; f++)
x+=a+b+c+d+e+f;
stopWatch->Stop();
TimeSpan ts = stopWatch->Elapsed;

System::Console::WriteLine("Nested Loop elapsed time: {0} sec.{1} msec.
{2}\n", ts.Seconds, ts.Milliseconds, x);
}

Nested Loop elapsed time: 12 sec.812 msec. 479232000000

Notice the result is slightly slower (dispite the O2 optimizing flag) than the
C# code, this is because the IL is constrained by the verifier (for both C#
and C++/CLI in safe mode). So here C# emits slightly better IL.

Willy.
 
M

Michael S

Peter Olcott said:
http://www.tommti-systems.de/go.htm...ain-Dateien/reviews/languages/benchmarks.html
The above link shows that C# is 450% slower on something as simple as a
nested loop. Is this because .NET is inherently slower or does the C#
compiler merely produce code that is not as well optimized as the C++
compiler?

As Nicholas gave a great link to a thread that have been done to death,
could we just stop this one?

Stop Feeding The Troll!

While I consider myself an expert in trolling, I hate when the unskilled
ones get all the attention I deserve =)

Happy Trolling
- Michael S
 
W

Willy Denoyette [MVP]

Peter Olcott said:
What is wrong with the benchmark?

Ever heard of integer overflow?
x (an integer type) cannot hold the value of +=a+b+c+d+e+f;
What's the value of a benchmark that produces wrong results?

Willy.
 
C

Christoph Nahr

That sure seems to be a moronic answer.

You sure seem to ask a lot of moronic questions. Willy already stated
what was wrong with the benchmark _and_ corrected it, in his post that
you obviously either didn't read or didn't understand.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top