473,385 Members | 1,400 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

C# v. C++ Performance

I read that C#'s JIT compiler produces very efficient
machine code. However, I've found when performing
extensive numerical calculations that C# is less than a
fourth the speed of C++. I give code examples below. Both
C# and C++ were compiled as release builds with default
optimisation on (C++ has /Ob1 set in addition to default
optimizations). I suspected the relatively poor C#
performance was due to using managed memory, but
adding 'unsafe' to relevant classes and methods makes
little or no difference.

I'd appreciate advice on how I can bring the C#
performance close to that of C++, or an acknowledgement
that for the code samples below, C# is fundamentally
several times slower than (unmanaged) C++.

C++ Code:

double total = 0.0;

for (int rep = 0; rep < 5; rep++)
{
total /= 1000.0;

for (long i = 0; i < 100000000; i++)
{
total += i/999999.0;
double disc = total*total + i;
double root = (total + disc)/
(200000.0*(i + 1));
total -= root;
}
}

C# Code:

double total = 0.0;

for (int rep = 0; rep < 5; rep++)
{
total /= 1000.0;

for (long i = 0; i <
100000000; i++)
{
total +=
i/999999.0;
double disc =
total*total + i;
double root =
(total + disc)/(200000.0*(i + 1));
total -= root;
}
}
Nov 15 '05 #1
14 7218
Longs 32bit in native code (C/C++) but are 64 bit in managed code, change
.... for (long i = 0; i < > 100000000; i++) in you C# code into for (int
i=...

Willy.
"Nigel" <ni***@nigelwilson.evesham.net.remove_this> wrote in message
news:0a****************************@phx.gbl...
I read that C#'s JIT compiler produces very efficient
machine code. However, I've found when performing
extensive numerical calculations that C# is less than a
fourth the speed of C++. I give code examples below. Both
C# and C++ were compiled as release builds with default
optimisation on (C++ has /Ob1 set in addition to default
optimizations). I suspected the relatively poor C#
performance was due to using managed memory, but
adding 'unsafe' to relevant classes and methods makes
little or no difference.

I'd appreciate advice on how I can bring the C#
performance close to that of C++, or an acknowledgement
that for the code samples below, C# is fundamentally
several times slower than (unmanaged) C++.

C++ Code:

double total = 0.0;

for (int rep = 0; rep < 5; rep++)
{
total /= 1000.0;

for (long i = 0; i < 100000000; i++)
{
total += i/999999.0;
double disc = total*total + i;
double root = (total + disc)/
(200000.0*(i + 1));
total -= root;
}
}

C# Code:

double total = 0.0;

for (int rep = 0; rep < 5; rep++)
{
total /= 1000.0;

for (long i = 0; i <
100000000; i++)
{
total +=
i/999999.0;
double disc =
total*total + i;
double root =
(total + disc)/(200000.0*(i + 1));
total -= root;
}
}

Nov 15 '05 #2
I can't offer much more than a comment at the moment, but in my experience
numerical calculations are precisely the area where C# should be on equal
ground with C++. I've had very good results with C# for intense numerical
computations. If, for some reason, you end up finding out the C# won't do
the job (I'd be surprised), you could always put the most performance
senstive code in C or C++ (even in an unmanaged DLL) and call it from C#.
I've done that before with very good results (only because some code was
already in C). The performance using PInvoke was really good.
HTH

"Nigel" <ni***@nigelwilson.evesham.net.remove_this> wrote in message
news:0a****************************@phx.gbl...
I read that C#'s JIT compiler produces very efficient
machine code. However, I've found when performing
extensive numerical calculations that C# is less than a
fourth the speed of C++. I give code examples below. Both
C# and C++ were compiled as release builds with default
optimisation on (C++ has /Ob1 set in addition to default
optimizations). I suspected the relatively poor C#
performance was due to using managed memory, but
adding 'unsafe' to relevant classes and methods makes
little or no difference.

I'd appreciate advice on how I can bring the C#
performance close to that of C++, or an acknowledgement
that for the code samples below, C# is fundamentally
several times slower than (unmanaged) C++.

C++ Code:

double total = 0.0;

for (int rep = 0; rep < 5; rep++)
{
total /= 1000.0;

for (long i = 0; i < 100000000; i++)
{
total += i/999999.0;
double disc = total*total + i;
double root = (total + disc)/
(200000.0*(i + 1));
total -= root;
}
}

C# Code:

double total = 0.0;

for (int rep = 0; rep < 5; rep++)
{
total /= 1000.0;

for (long i = 0; i <
100000000; i++)
{
total +=
i/999999.0;
double disc =
total*total + i;
double root =
(total + disc)/(200000.0*(i + 1));
total -= root;
}
}

Nov 15 '05 #3
Nigel <ni***@nigelwilson.evesham.net.remove_this> wrote:
I read that C#'s JIT compiler produces very efficient
machine code.
C# doesn't have a JIT compiler. .NET has a JIT compiler. You need to be
very clear on where the boundaries are.
However, I've found when performing
extensive numerical calculations that C# is less than a
fourth the speed of C++. I give code examples below. Both
C# and C++ were compiled as release builds with default
optimisation on (C++ has /Ob1 set in addition to default
optimizations). I suspected the relatively poor C#
performance was due to using managed memory, but
adding 'unsafe' to relevant classes and methods makes
little or no difference.

I'd appreciate advice on how I can bring the C#
performance close to that of C++, or an acknowledgement
that for the code samples below, C# is fundamentally
several times slower than (unmanaged) C++.


C# itself is a language, not an implementation. However, assuming that
weren't actually a problem... "fundamentally" is a very strange word to
use here - there are certain benchmarks that could no doubt be produced
where C++ ends up slower than C# - how can two languages themselves
each be "fundamentally" slower than the other?

There are certain situations where C++ will be faster than C#, and vice
versa.

Now, let's look at your case in point. Here are the raw numbers from my
laptop - not the ideal testing scenario, but not a bad starting point:

First run:
C++: 27s
C#: 70s

Already this is less than the factor of four you were quoting - indeed,
it's not even three times as slow. Still, let's see what we can do...

There looks to be a lot of casting from long to double here. Changing
the C# code to:

for (int rep = 0; rep < 5; rep++)
{
total /= 1000.0;

for (double i = 0; i < 100000000d; i+=1.0d)
{
total += i/999999.0;
double disc = total*total + i;
double root = (total + disc)/(200000.0*(i + 1.0d));
total -= root;
}
}

the execution time for C# goes down to just 18 seconds! (The results
appear to be the same, and I can't see why it wouldn't be a perfectly
valid optimisation to perform - the only possible loss of precision
would be where converting (i+1) to a double would have a different
result to adding 1.0 to the double value of i. I've verified that
doesn't occur anywhere in the range 0-100000000; in actual code you
might want to check whether or not it could be a problem.

Changing the C++ code in a similar way doesn't appear to help it.

So, according to the above, would you acknowledge that "C# is
fundamentally significantly faster than (unmanaged) C++" or would you
acknowledge that single benchmarks aren't necessarily a good indication
of an entire platform?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #4
Thats a first run, try a second run for a warm start.
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Nigel <ni***@nigelwilson.evesham.net.remove_this> wrote:
I read that C#'s JIT compiler produces very efficient
machine code.


C# doesn't have a JIT compiler. .NET has a JIT compiler. You need to be
very clear on where the boundaries are.
However, I've found when performing
extensive numerical calculations that C# is less than a
fourth the speed of C++. I give code examples below. Both
C# and C++ were compiled as release builds with default
optimisation on (C++ has /Ob1 set in addition to default
optimizations). I suspected the relatively poor C#
performance was due to using managed memory, but
adding 'unsafe' to relevant classes and methods makes
little or no difference.

I'd appreciate advice on how I can bring the C#
performance close to that of C++, or an acknowledgement
that for the code samples below, C# is fundamentally
several times slower than (unmanaged) C++.


C# itself is a language, not an implementation. However, assuming that
weren't actually a problem... "fundamentally" is a very strange word to
use here - there are certain benchmarks that could no doubt be produced
where C++ ends up slower than C# - how can two languages themselves
each be "fundamentally" slower than the other?

There are certain situations where C++ will be faster than C#, and vice
versa.

Now, let's look at your case in point. Here are the raw numbers from my
laptop - not the ideal testing scenario, but not a bad starting point:

First run:
C++: 27s
C#: 70s

Already this is less than the factor of four you were quoting - indeed,
it's not even three times as slow. Still, let's see what we can do...

There looks to be a lot of casting from long to double here. Changing
the C# code to:

for (int rep = 0; rep < 5; rep++)
{
total /= 1000.0;

for (double i = 0; i < 100000000d; i+=1.0d)
{
total += i/999999.0;
double disc = total*total + i;
double root = (total + disc)/(200000.0*(i + 1.0d));
total -= root;
}
}

the execution time for C# goes down to just 18 seconds! (The results
appear to be the same, and I can't see why it wouldn't be a perfectly
valid optimisation to perform - the only possible loss of precision
would be where converting (i+1) to a double would have a different
result to adding 1.0 to the double value of i. I've verified that
doesn't occur anywhere in the range 0-100000000; in actual code you
might want to check whether or not it could be a problem.

Changing the C++ code in a similar way doesn't appear to help it.

So, according to the above, would you acknowledge that "C# is
fundamentally significantly faster than (unmanaged) C++" or would you
acknowledge that single benchmarks aren't necessarily a good indication
of an entire platform?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #5
<di********@discussion.microsoft.com> wrote:
Thats a first run, try a second run for a warm start.


I ran the code several times, actually (both versions). For the .NET
version, I only timed the code between the start of the method
executing and the end - the only JIT compilation time required would be
for Console.WriteLine and DateTime.Now. Unlike Java, .NET only JITs
once so you don't need to run the same method many times in order to
get the code to run as fast as possible - aside from the time spent to
JIT in the first place, it's running as fast as it's going to by the
time it's running the first time.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #6
Jon,

The main problem with OP's code is the for loop using longs, which are as
you know 64 bit in .NET and 32 bit in native code.
Quite a diffrerence if you are adding/comparing a 32 bit vs. a 64 bit entity
on a 32 bit CPU....( and this 100.000.000 times)

Using for(int i=0; i<...
Both C++ and C# took the same time to run to completion.

Willy.

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Nigel <ni***@nigelwilson.evesham.net.remove_this> wrote:
I read that C#'s JIT compiler produces very efficient
machine code.


C# doesn't have a JIT compiler. .NET has a JIT compiler. You need to be
very clear on where the boundaries are.
However, I've found when performing
extensive numerical calculations that C# is less than a
fourth the speed of C++. I give code examples below. Both
C# and C++ were compiled as release builds with default
optimisation on (C++ has /Ob1 set in addition to default
optimizations). I suspected the relatively poor C#
performance was due to using managed memory, but
adding 'unsafe' to relevant classes and methods makes
little or no difference.

I'd appreciate advice on how I can bring the C#
performance close to that of C++, or an acknowledgement
that for the code samples below, C# is fundamentally
several times slower than (unmanaged) C++.


C# itself is a language, not an implementation. However, assuming that
weren't actually a problem... "fundamentally" is a very strange word to
use here - there are certain benchmarks that could no doubt be produced
where C++ ends up slower than C# - how can two languages themselves
each be "fundamentally" slower than the other?

There are certain situations where C++ will be faster than C#, and vice
versa.

Now, let's look at your case in point. Here are the raw numbers from my
laptop - not the ideal testing scenario, but not a bad starting point:

First run:
C++: 27s
C#: 70s

Already this is less than the factor of four you were quoting - indeed,
it's not even three times as slow. Still, let's see what we can do...

There looks to be a lot of casting from long to double here. Changing
the C# code to:

for (int rep = 0; rep < 5; rep++)
{
total /= 1000.0;

for (double i = 0; i < 100000000d; i+=1.0d)
{
total += i/999999.0;
double disc = total*total + i;
double root = (total + disc)/(200000.0*(i + 1.0d));
total -= root;
}
}

the execution time for C# goes down to just 18 seconds! (The results
appear to be the same, and I can't see why it wouldn't be a perfectly
valid optimisation to perform - the only possible loss of precision
would be where converting (i+1) to a double would have a different
result to adding 1.0 to the double value of i. I've verified that
doesn't occur anywhere in the range 0-100000000; in actual code you
might want to check whether or not it could be a problem.

Changing the C++ code in a similar way doesn't appear to help it.

So, according to the above, would you acknowledge that "C# is
fundamentally significantly faster than (unmanaged) C++" or would you
acknowledge that single benchmarks aren't necessarily a good indication
of an entire platform?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #7
Willy Denoyette [MVP] <wi*************@pandora.be> wrote:
The main problem with OP's code is the for loop using longs, which are as
you know 64 bit in .NET and 32 bit in native code.
Quite a diffrerence if you are adding/comparing a 32 bit vs. a 64 bit entity
on a 32 bit CPU....( and this 100.000.000 times)
Yes - I even thought about that as I was originally responding, but had
a brain fart and didn't end up picking it up properly.
Using for(int i=0; i<...
Both C++ and C# took the same time to run to completion.


Actually, when I ran it, C# had the edge using ints on my box - 20s vs
27s. However, using a double for the loop counter is even faster (18s).

Interestingly, I thought I'd get rid of the duplicate (i+1) by having
another variable which would act as the next value of i and the amount
to multiply by 200000 - but that decreased performance. I haven't
managed to increase performance beyond that 18s mark.

I've just tried with /O2 on the C++ version, and that actually runs in
about 15s, so there's still room for improvement in the CLR, but it's
still very impressive, IMO.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #8
On Mon, 8 Dec 2003 23:53:34 -0000, Jon Skeet [C# MVP]
<sk***@pobox.com> wrote:
So, according to the above, would you acknowledge that "C# is
fundamentally significantly faster than (unmanaged) C++" or would you
acknowledge that single benchmarks aren't necessarily a good indication
of an entire platform?


Actually, C++ is infinitely faster than C# because VC++ 7.1 with the
/Ox switch optimized away the entire loop!

After inserting a "return (int) total;" statement at the end so that
the loop was actually executed, optimized builds for both languages
performed at about the same speed on my system (~12 seconds), with C++
coming out slightly ahead (let's say 11.5 seconds). The C# version
was of course fixed to use an int counter instead of a long counter.

That was one remarkably poor "benchmark" that the OP used. Isn't
there some "Benchmarks for Dummies" book that could be recommended in
such cases? If you have lots of time you might want to add a
benchmarking section to your page, seeing how you already took care of
the floating-point and Unicode questions. ;-)
--
http://www.kynosarges.de
Nov 15 '05 #9
How does the JIT handle dynamic code?

What if I change a class during runtime (it can be done)

Self modifying code for example, GAs.

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
<di********@discussion.microsoft.com> wrote:
Thats a first run, try a second run for a warm start.


I ran the code several times, actually (both versions). For the .NET
version, I only timed the code between the start of the method
executing and the end - the only JIT compilation time required would be
for Console.WriteLine and DateTime.Now. Unlike Java, .NET only JITs
once so you don't need to run the same method many times in order to
get the code to run as fast as possible - aside from the time spent to
JIT in the first place, it's running as fast as it's going to by the
time it's running the first time.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #10
a Double is faster? Why.
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Willy Denoyette [MVP] <wi*************@pandora.be> wrote:
The main problem with OP's code is the for loop using longs, which are as you know 64 bit in .NET and 32 bit in native code.
Quite a diffrerence if you are adding/comparing a 32 bit vs. a 64 bit entity on a 32 bit CPU....( and this 100.000.000 times)


Yes - I even thought about that as I was originally responding, but had
a brain fart and didn't end up picking it up properly.
Using for(int i=0; i<...
Both C++ and C# took the same time to run to completion.


Actually, when I ran it, C# had the edge using ints on my box - 20s vs
27s. However, using a double for the loop counter is even faster (18s).

Interestingly, I thought I'd get rid of the duplicate (i+1) by having
another variable which would act as the next value of i and the amount
to multiply by 200000 - but that decreased performance. I haven't
managed to increase performance beyond that 18s mark.

I've just tried with /O2 on the C++ version, and that actually runs in
about 15s, so there's still room for improvement in the CLR, but it's
still very impressive, IMO.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #11
<di********@discussion.microsoft.com> wrote:
How does the JIT handle dynamic code?

What if I change a class during runtime (it can be done)
I don't believe a class *can* be changed during runtime in .NET - at
least not yet. VB.NET will have "edit and continue" functionality in
the next version of VS.NET, which requires that kind of facility, but I
don't believe it's available yet.
Self modifying code for example, GAs.


Could you give an exmaple of that occurring in .NET? A class could
create a *new* class, of course, but that's a different matter.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #12
<di********@discussion.microsoft.com> wrote:
a Double is faster? Why.


Adding 1 to a double is very quick, but apparently converting from int
or long to double isn't quite as quick. Or at least, the two additions
and one double comparison required in the modified code are faster than
the three int->double conversions, 2 integer adds and one integer
comparison required in the original (or modified from long->int) code.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #13
Cant you build a type at runtime and
get it via reflection?

Im not talking about user generated, im talking programatically.

Edit and continue has jack to do with it.

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
<di********@discussion.microsoft.com> wrote:
How does the JIT handle dynamic code?

What if I change a class during runtime (it can be done)


I don't believe a class *can* be changed during runtime in .NET - at
least not yet. VB.NET will have "edit and continue" functionality in
the next version of VS.NET, which requires that kind of facility, but I
don't believe it's available yet.
Self modifying code for example, GAs.


Could you give an exmaple of that occurring in .NET? A class could
create a *new* class, of course, but that's a different matter.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #14
<di********@discussion.microsoft.com> wrote:
Cant you build a type at runtime and get it via reflection?
Yes. That's *creating* a type though, not changing an existing one.
Im not talking about user generated, im talking programatically.
Sure, but that's not the same as changing a class during runtime.
Edit and continue has jack to do with it.


Edit and continue has *everything* to do with it - it requires that a
type which has already been loaded and JITted can then be modified and
the code reJITted. *That* is changing a class at runtime.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

25
by: Brian Patterson | last post by:
I have noticed in the book of words that hasattr works by calling getattr and raising an exception if no such attribute exists. If I need the value in any case, am I better off using getattr...
12
by: Fred | last post by:
Has anyone a link or any information comparing c and c++ as far as execution speed is concerned? Signal Processing algorithms would be welcome... Thanks Fred
12
by: serge | last post by:
I have an SP that is big, huge, 700-800 lines. I am not an expert but I need to figure out every possible way that I can improve the performance speed of this SP. In the next couple of weeks I...
6
by: teedilo | last post by:
We have an application with a SQL Server 2000 back end that is fairly database intensive -- lots of fairly frequent queries, inserts, updates -- the gamut. The application does not make use of...
5
by: Scott | last post by:
I have a customer that had developed an Access97 application to track their business information. The application grew significantly and they used the Upsizing Wizard to move the tables to SQL...
115
by: Mark Shelor | last post by:
I've encountered a troublesome inconsistency in the C-language Perl extension I've written for CPAN (Digest::SHA). The problem involves the use of a static array within a performance-critical...
13
by: bjarne | last post by:
Willy Denoyette wrote; > ... it > was not the intention of StrousTrup to the achieve the level of efficiency > of C when he invented C++, ... Ahmmm. It was my aim to match the performance...
13
by: Bern McCarty | last post by:
I have run an experiment to try to learn some things about floating point performance in managed C++. I am using Visual Studio 2003. I was hoping to get a feel for whether or not it would make...
7
by: Michael D. Ober | last post by:
When calling Enqueue, the internal array may need to be reallocated. My question is by how much? In the old MFC array classes, you could tell MFC how many additional elements to add to the array...
1
by: jvn | last post by:
I am experiencing a particular problem with performance counters. I have created a set of classes, that uses System.Diagnostics.PerformanceCounter to increment custom performance counters (using...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.