4

When calling C++ functions from C# code, which way gives the best performance?

  • COM interop
  • C++-CLI (is that future proof?)
  • HTTP REST API
  • Something else?

I imagine that COM interop gives best performance, and that the performance falls quickly when you go down the list. Or am I completely wrong?

Background

We have a old central server application written in C++/MFC. Today, there are no easy ways for other applications to communicate with this application, and we want to develop an API for it.

In today's application, performance is important, and we want reasonably high performance even in those applications that use the new API.

The applications that will use the API will be written in both C++, C# and PowerShell. Probably, some sort of Facade must be made for each language, but we do not want it to be too much work to keep the different facades updated with changes in the API. The best thing would have been if the Facades were automated generated at compilation.

Edit

With Functions, I mean functions to get status, get and set information in the internal database (that can be long text strings), etc

Thomas Flinkow
  • 4,845
  • 5
  • 29
  • 65
magol
  • 6,135
  • 17
  • 65
  • 120
  • What do you mean by a _C++ function_? As-is, this is too broad / opinion based. – Ron Jun 06 '18 at 12:17
  • Functions to get status, get and set information in the internal database, etc – magol Jun 06 '18 at 12:18
  • 1
    HTTP is clearly the best in terms of capabilities of integration with all OSes and languages in the universe. It's also the slowest. But all that doesn't mean nothing w/o real numbers, volumes, etc. "reasonable high performance", "C++, C#, PowerShell, etc." is useless ("etc.." means what?). If you only need Windows support but really want C++, COM may be the choice. Everything is a compromise. – Simon Mourier Jun 06 '18 at 13:16
  • 3
    There is no major difference between COM, C++/CLI and pinvoke with [DllImport], they all do the basic same thing. Only C++/CLI gives you a shot at micro-optimizing, COM and pinvoke are automagic. The root cost of the interop call is very low, a handful of CPU cycles. But the added cost of converting function parameters from their managed flavor to the native flavor can make it balloon. String conversion and array element copying for non-blittable types can add up. As usual, perf is determined by programmer skill and not the plumbing. – Hans Passant Jun 06 '18 at 13:23

1 Answers1

5

See this for a bit more information by Microsoft themselves.

Other than that; it seems that P/Invoke is the fastest (e.g. see this). Speaking from experience I can say that P/Invoke is pretty fast (75 μs per call compared to 1.4 μs for C# only) but this is of course not universally valid and YMMV.

Furthermore, while P/Invoke is pretty fast, it is quite unsafe and often simply a pain in the ***. Same goes for COM Interop since both lack all the syntactic sugar and simplicity that C# - and to a certain extent, C++/CLI - offer. They also lead to much more verbose code.

This is where C++ CLI comes in handy. It makes writing the interop code way easier and safer than with P/Invoke or COM. It is less verbose as well.

Much more important however is that P/Invoke does not work with C++. It works with C only, so you will always need at least a thin wrapper layer for your C++ code (e.g. extern "C", no classes etc.) while C++/CLI works with C++ and all the nice stuff such as std::string too.


Conclusion: it's important to not choose what is the fastest in terms of runtime, but rather in terms of development time: do you want to spend 8+ hours to hunt down a nasty memory leak introduced by not carefully written P/Invoke just to gain that extra +10us?

Choose what is most readable and most safe - not what is a tiny bit faster than the other. Optimizations can and should be done rather at the end.

Thomas Flinkow
  • 4,845
  • 5
  • 29
  • 65
  • .. just to gain that extra +10us? I know what you mean. but for measurement applications this may matters. (GPIB, USB, TCP interface, NI488.2 vs VISA API). It can be worthwhile to invest time on this. But again here, you can gain much more time with the right device configuration. (study the manuals and test it thoroughly) – Tom Tom May 14 '20 at 10:27