3

I am building a prototype for a quantitative library that does some signal analysis using image processing techniques. I built the initial prototype entirely in C#, but the performance is not as good as expected. Most of the computation is done through heavy matrix calculations, and these are taking up most of the time.

I am wondering if it is worth it to write a C++/CLI interface to unmanaged C++ code. Has anyone ever gone through this? Other suggestions for optimizing C# performance is welcome.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
thomas1234
  • 599
  • 3
  • 6
  • 15
  • 5
    Not sure we could offer accurate guidance without seeing some code. You could, in theory, write more performant code in C++... but you could also write much worse code in C++. – Andrew Barber Nov 16 '10 at 16:04
  • 1
    Before you go to the trouble of writing C++/CLI code, find out why your C# code is slow using a profiler, such as JetBrains dotTrace, RedGate ANTS, etc. Depending on the bottleneck, you might be able to remove it by re-working some of your C# code, judicious use the unsafe keyword and pointers in C#, or re-writing the core parts in C++. The best solution is going to depend on the bottleneck. Remember that you might end up with worse perf due to marshaling overhead than a pure C++ solution. So make sure you know what you're trying to fix. – James Kovacs Nov 16 '10 at 16:13
  • 1
    @Andrew, I would say C# prevents the programmer to do worse coding by providing many out of the box solutions. It is not fair to compare C# coding and some code badly written in C++. – Jimmy Nov 16 '10 at 17:51
  • @thomas1234- Given the generalised nature of this question, the answer is unmanaged C++ will be faster. – Jimmy Nov 16 '10 at 17:55
  • @Jimmy +1 because I agree completely with your comment; I was just more looking at the "Let's move it to C++ to make it faster" angle solely from the C++ side of it. Your comment completes that thought, though. Properly coded, C# makes it easier to get "pretty darn good performance". – Andrew Barber Nov 16 '10 at 19:21
  • @Andrew, I agree with you in this – Jimmy Nov 17 '10 at 14:55

8 Answers8

3

There was a time where it would definitely be better to write in C/C++, but the C# optimizer and JIT is so good now, that for pure math, there's probably no difference.

The difference comes when you have to deal with memory and possibly arrays. Even so, I'd still work with C# (or F#) and then optimize hotspots. The JIT is really good at optimizing away small, short-lived objects.

With arrays, you have to worry about C# doing bounds-checks on each access. Read this:

Link

Test it yourself -- I've been finding C# to be comparable -- sometimes faster.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Lou Franco
  • 87,846
  • 14
  • 132
  • 192
  • 1
    The JIT can't do anything to optimize pure number-crunching, and it still has to deal with a lot of overhead. C# may be faster than C++ for some code, but C# will never be as fast as well-optimized C++ for numbercrunching. – Chris Nov 16 '10 at 16:17
  • 1
    I write image processing code for a living and am doing extensive performance testing. It's just not true that C/C++ is always faster than C#. There are big disadvantages to C/C++ in the .NET world (can't be run in Silverlight and other safe environments). When you decide to add multi-thread to the mix, C#/F# will blow C/C++ away. – Lou Franco Nov 16 '10 at 16:45
  • @Lou: not sure why on the last part. Why is C# superior to C++ in terms of multithreading? (On the performance front, I largely agree with you, it's *probably* not worth writing in C++. – jalf Nov 16 '10 at 17:37
  • @Lou, Could you just give an example where C#.NET runs better than native C++? – Jimmy Nov 16 '10 at 17:47
  • @jalf, the .NET platform gives you all kinds of help to make the code easy -- also see F#'s approach. – Lou Franco Nov 16 '10 at 18:51
  • 1
    @Jimmy the easiest one to explain is reference counting vs. garbage collection -- when you use a lot of short-lived small objects, the GC can easily beat reference counting. Not all C++ programs need pervasive reference counting, but if you have any kind of non-trivial object lifetime, you probably will. Also, if you are called from C#, you pay a context-switch penalty every time you cross the managed/unmanaged boundary -- so API's with a heavy C backend cannot be granular. If you want a rich communication channel (with lots of little calls and callbacks), the context-switching can dominate. – Lou Franco Nov 16 '10 at 18:52
  • @Lou A good C++ programmer puts short-lived small objects on the stack, beating both reference counting and garbage collecting. I agree on everything you said about context-switches, though. – Sjoerd Nov 17 '10 at 08:58
  • @Sjoerd -- If you put std::string on the stack, it still reference counts. – Lou Franco Nov 18 '10 at 05:24
3

It's hard to give a definitive answer here, but if performance is an issue I'd find a time-tested library with the performance you need and wrap it.

Something simple like multiplication or division is not much different between c++ and c# - the c++ compiler has an optimizer, and the CLR runtime has the on-demand JITer that does optimizations. So in theory, the c++ would outperform c# only on the first call.

However, theory and practice are not the same. With more complicated algorithms you also run into the differences between memory managers, and the maturity of the optimization techniques. If you want anecdotal evidence, you can find some math-heavy comparisons here.

Personally, I find doing the heavy computations in a native library and using c++/CLI to call it gives a good boost when the computations are the biggest bottleneck. As always, make sure that's the case before doing any optimization.

Philip Rieck
  • 32,368
  • 11
  • 87
  • 99
  • 1
    Came here to say this. There are a lot of extremely well-optimized C/C++ libraries for signal and image processing. If that's the bottleneck, someone has already done the dirty work for you. – Chris Nov 16 '10 at 16:21
  • >> you can find some math-heavy comparisons here << The programs in that Feb 2009 blog posting seem to have been taken from "The Computer Language Benchmarks Game". – igouy Nov 16 '10 at 17:23
2

Matrix math is best done in native code in my opinion. Even the C++ libraries typically allow binding to a lower-level implementation like LAPACK.

There is a C# LAPACK port here (also C# BLAS on the same site) which you could try but I'd be surprised if this is faster than native code.

Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
1

I've done a lot of image processing work in C# and, yes, I usually do use native code for heavy duty code where performance matters but I used just PInvokes and not the C++/CLI interface. A lot of time this is not needed, though.

There's quite a few good .NET profilers. The Red Gate one is my personal favorite. It might help you to visualize where the bottlenecks are.

Vitor Py
  • 5,145
  • 4
  • 39
  • 62
1

The only reasonable language benchmark out there: http://shootout.alioth.debian.org/

See for yourself.

Šimon Tóth
  • 35,456
  • 20
  • 106
  • 151
0

You should write computational heavy programs in C++, you cannot reach anywhere near to C++ performance by optimizing C#. The overhead of calling wrappers is negligible assuming the computation takes considerable time. I have done coding in both C++ and C# and have never seen any occasion where .NET framework code come comparable to C++. There are a few instances where C# where runs better, but it was better because of lack of appropriate libraries or bad coding in C++. If you can write code equally well in C# and C++, I would write performance code in C++ and everything else is C#.

If x is the world best C++ programmer and y is the best C# programmer then most of the times x can write faster code than y. However, y can finish the coding faster than x most of the times.

Jimmy
  • 3,224
  • 5
  • 29
  • 47
0

Performance for mathematical computation is pretty poor in C#. I was gobbsmacked to find how slow mathematical calculations are in C#. Just write a loop in C# and C++ having a few Multiplication, Sin, Cos, ... and the difference is immense.

I do not know Managed C++ but imlpementing it all in unmanaged C++ abd I would umagine exposing granular interfaces through P/Invoke should have little perfromance hit.

That is what I have done for heavy real-time image processing.

Aliostad
  • 80,612
  • 21
  • 160
  • 208
0

I built the initial prototype entirely in C#, but the performance is not as good as expected.

then you have two options:

Build another prototype in C++, and see how that compares, or optimize your C# code. No matter what language you write in, your code won't be fast until you've profiled and optimized and profiled and optimized it. That is especially true in C++. If you write the fastest possible implementation in C# and compare it to the fastest possible implementation in C++, then the C++ version will most likely be faster. But it will come at a cost in terms of development time. It's not trivial to write efficient C++ code. If you are new to the language then you will most likely write very inefficient code, especially if you are coming from C# or Java, where things are done differently and have different costs.

If you just write a working implementation, without worrying too much about performance, then I'm guessing that the C# version will probably be faster.

But it really depends on what kind of performance you're after (and not least, how expensive the operations you need to perform are. There's an overhead associated with the transition from managed to native code, so it is not worth it for short operations that are executed often.

Number-crunching code in C++ can be as fast as code written in Fortran (give or take a few percent), but to achieve that, you need to use a lot of advanced techniques (expression templates and lots of metaprogramming) or some fairly complex libraries which implement it for you.

Is that worth it? Or can C# be made fast enough for your needs?

jalf
  • 243,077
  • 51
  • 345
  • 550