views:

126

answers:

2

In a C# to native lib CLI/C++ wrapper, I have a choice:

  • Store native pointer in a managed class (native object is created using native "new")

or

  • Store native object as a data blob in a managed class' field, and use pin_ptr to pin it before each native use.

Has anyone done any comparative analysis on the relative performance costs of the two paths?

Thanks!

+1  A: 

pin_ptr is to prevent objects on the managed heap from being moved by the GC when its address is being passed to native function functions who aren't aware the chair could be pulled by the GC. It does not affect memory allocated on the native heap or on the stack.

Storing native object as blob in a managed class is what managed C++ did for mixed types. It was too easy to returns a pointer to memory on the garbage collected heap that is not pinned and could crash the app later on, and this problem is too hard to debug. This problem is so common (people do not expect the chair can be pulled by GC) that Microsoft decided to disable mixed type altogether so people have to explicitly specify where the object's memory is.

Sheng Jiang 蒋晟
It's essentially the same issue as returning the address of a local variable... so experienced C++ programmers aren't bothered but anyone coming from the managed world might have difficulty.
Ben Voigt
+1  A: 

There's probably not much difference. GC allocation is actually slightly faster than native new. And pinning is only a performance problem if the object is pinned when the GC does a collection. If the managed object ends up big enough to go into the LOH, then pinning is free.

But I haven't measured it myself.

What I wouldn't do is use a GCHandle to keep the object pinned between function calls. That's more expensive to set up than a pin_ptr and more likely to impact the GC. For data that needs to stay permanently in place, use the native allocator.

Ben Voigt