Can C# be as fast as C++?

J

Juan Dent

Hi,

I need to know if someone has made benchmarks to investigate the performance
of NGEN'ed C# code versus pure C++ native code. I once heard NGEN'ed C#
*could* be faster because it generates native code that takes into account
the capacities of the processor in the machine.

In my case, the code needs to use some COM objects for which I could create
wrappers in C++/CLI - instead of building Interop Assemblies - for C#
consumption. I don't think these wrappers will pose any noticeable weight in
the performance.

My second question is memory usage. A friend of mine says that every time he
opens a C# application the memory consumption goes too high, and we need the
program to run in RAM restricted environments. Is this true? Can it be tuned?
If it is true, what causes it?
 
A

Arne Vajhøj

Juan said:
I need to know if someone has made benchmarks to investigate the performance
of NGEN'ed C# code versus pure C++ native code. I once heard NGEN'ed C#
*could* be faster because it generates native code that takes into account
the capacities of the processor in the machine.

NGEN'ed code are not faster than code JIT'ed when run. NGEN only reduces
startup time by precompiling.

C# code can be as fast as C++ code or slower depending
on what it does and how it is coded.
My second question is memory usage. A friend of mine says that every time he
opens a C# application the memory consumption goes too high, and we need the
program to run in RAM restricted environments. Is this true? Can it be tuned?
If it is true, what causes it?

Two effects: .NET runtime do require some memory, .NET memory management
does not release memory if it is not needed so on a system with plenty
of memory .NET really tries to utilize it.

Arne
 
J

Jon Harrop

Juan said:
I need to know if someone has made benchmarks to investigate the
performance of NGEN'ed C# code versus pure C++ native code.

I've benchmarked C# vs C++ and other languages. The outcome depends entirely
upon the style of program.

If you write code that allocates heavily (like symbolic manipulation) then
C# has a comparatively good run-time system behind it where as C++ has
nothing so you'll realistically tack on something awful like Boehm's GC and
the performance of the C++ will go through the floor.

If your task is soft real-time then you'll be interested in worst case
performance. C++ is very poor for that by design (avalanching destructors)
and C# is likely to be much faster (generational concurrent GC). On our
250kLOC application code we found OCaml (another garbage collected
language) to be over 5x faster than C++ for this reason.

If you're handling lots of big structs with unboxing then .NET's performance
might suffer because some optimizations are not yet implemented. Same for
heavily abstracted numerical programs that would benefit from aggressive
inlining. In which case, C++ may well be faster.

With no information about your programs I can't advise which category they
will fall into.
My second question is memory usage. A friend of mine says that every time
he opens a C# application the memory consumption goes too high, and we
need the program to run in RAM restricted environments. Is this true? Can
it be tuned? If it is true, what causes it?

I'm not too familiar with C#'s memory usage but STL implementations in C++
standard libraries tend to have awful memory consumption characteristics.
That was actually the reason we ditched C++ a few years back and that was
for desktop systems! If you want to keep that under control then do your
own C-style memory management. Again, this depends how "constrained" your
memory is.
 
M

Michael A. Covington

Jon Harrop said:
I've benchmarked C# vs C++ and other languages. The outcome depends
entirely
upon the style of program.

If you write code that allocates heavily (like symbolic manipulation) then
C# has a comparatively good run-time system behind it where as C++ has
nothing so you'll realistically tack on something awful like Boehm's GC
and
the performance of the C++ will go through the floor.

That is why I like C# for artificial intelligence research. It has much the
same appeal as the old Lisp machines did -- it's easy to create complex data
structures and put a good GUI on whatever we're implementing.
 
M

Marra

I had some seriously bad experiences with early C++ so was plesantly
suprised how well I got on with C#.

I have written a few tens of thousands of lines in C# and it seems to
run fairly quickly.
 
B

Ben Voigt [C++ MVP]

Juan Dent said:
Hi,

I need to know if someone has made benchmarks to investigate the
performance
of NGEN'ed C# code versus pure C++ native code. I once heard NGEN'ed C#
*could* be faster because it generates native code that takes into account
the capacities of the processor in the machine.

There's a significant possibility that the machine specific optimizations
are only done during JIT, as NGEN places the result in a file which can be
moved around.
In my case, the code needs to use some COM objects for which I could
create
wrappers in C++/CLI - instead of building Interop Assemblies - for C#
consumption. I don't think these wrappers will pose any noticeable weight
in
the performance.

My second question is memory usage. A friend of mine says that every time
he
opens a C# application the memory consumption goes too high, and we need
the
program to run in RAM restricted environments. Is this true? Can it be
tuned?
If it is true, what causes it?

Actually, C++/CLI will give you all the (run-time) advantages of C# along
with a few of the advantages of native C++ (the optimizing compiler is much
better than the JIT, and all NGEN does is run the JIT).

The only thing C# has over C++/CLI is that all the effort into the Visual
Studio wizards and designers has been focused on C#.
 
J

Jon Skeet [C# MVP]

There's a significant possibility that the machine specific optimizations
are only done during JIT, as NGEN places the result in a file which can be
moved around.

I believe the ngen'd file has a record of various machine-specific
attributes (such as processor type) and will be ignored if they're
wrong. However, I've *also* heard that ngen doesn't have all of the
optimizations of the normal JIT - I'm not sure how to square these
two. I suppose the normal JIT is able to do cross-assembly inlining
which could be tricky in ngen, etc.

Jon
 
S

Shawn B.

There's a significant possibility that the machine specific optimizations
I believe the ngen'd file has a record of various machine-specific
attributes (such as processor type) and will be ignored if they're
wrong. However, I've *also* heard that ngen doesn't have all of the
optimizations of the normal JIT - I'm not sure how to square these
two. I suppose the normal JIT is able to do cross-assembly inlining
which could be tricky in ngen, etc.

This also depends. NGEN is different for both 64-bit and 32-bit Intel/AMD
CPU's. The JIT for 32-bit was written by the C# team, IIRC, and the C++
team wrote the JIT/NGEN for 64-bit so its much more in-tune with the C++
optimimizer <grin>. IIRC, the 64-bit JIT/NGEN was written from scratch. At
least this is what I read and I read it a while ago just before Whidbey was
released.

However, when I look at the code generation for C# on both 32/64-bit
versions, the C# compiler doesn't seem to produce as much optimal IL
instructions as the C++/CLI compiler (for obvious reasons). What is
interesting that if I hand-tuned some IL instructions from C# programs (for
example, changing some things in ways that would remove, say, 8 out of 49 IL
instructions, or simply rearrage the sequence of instructions, on 32-bit
JIT, during profiling, would produce worse for some reason but on 64-bit
performs better. Hard to know exactly why. I figured that the 32-bit JIT
looked for patterns that C#/VB.NET (nearly identicle output) produce and
optimizes that and by hand-tuning some IL it broke the pattern recognition
but, in reality, I have no idea whether that is the truth.

Having written my own C# compiler that allows me to dynamically add new
syntax and language features on a per-project or per-assembly
(referenceable) basis, I've sound ways to write IL that produce good
results. I had to spend insane amounts of time looking at what C#/VBn/C++
CLI produced and figured out what works best. In the end, I produce my own
opcode sequences in some areas where I found advantages in doing so.

Now all we need is a way for IL to express something that very easily maps
to SSE2/3/4//altivec/etc.. so I can optimize some of my numericals.


Thanks,
Shawn
 
B

Bill Woodruff

Shawn B wrote :

"Having written my own C# compiler that allows me to dynamically add new
syntax and language features on a per-project or per-assembly
(referenceable) basis, I've sound ways to write IL that produce good
results. I had to spend insane amounts of time looking at what C#/VBn/C++
CLI produced and figured out what works best. In the end, I produce my own
opcode sequences in some areas where I found advantages in doing so."

Hope you'll publish an account of your work, and thoughts about what you
learned from it on CodeProject or some public site. I'm sure I would benefit
from reading.

thanks, Bill Woodruff
dotScience
Chiang Mai, Thailand
 

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