Would you get better performance? Depends on what you're doing and how you're doing it. Generally speaking, your performance hit will more likely come from doing managed/unmanaged transitions and the more of those you can cut out the better. Ideally, your interfacing to unmanaged code should be chunky and not chatty.
Let's say that you have a unmanaged code that has a collection of a few thousand objects. You could expose an API like this to managed code:
int GetFooCount();
IntPtr GetFoo(int n);
void ReleaseFoo(IntPtr p);
and that's all well and good, until you start using it in C# like this:
int total = API.GetFooCount();
IntPtr[] objects = new IntPtr[total];
for (int i=0; i < total; i++) {
objects[i] = GetFoo(i);
}
// and later:
foreach (IntPtr p in objects) { ReleaseFoo(p); }
which for total == 1000, will be 4002 managed/unmanaged transitions. If instead you have this:
int GetFooCount();
void GetFoos(IntPtr[] arr, int start, int count);
void ReleaseFoos(IntPtr arr, int start, int count);
then you can do the same work with 6 transitions. Which do you think will perform better?
Of course, the next important question to ask is "is this performance gain worthwhile?" so remember to measure first.
One thing you should be aware of as well is that funny things can happen to STL when you're working with managed C++. I have some unmanaged library code which happens to use STL. My experience was that if I ever touched any of the STL types in managed C++, ALL of them became managed implementations. The end result of this was that low level code was doing managed/unmanaged transitions while iterating lists. Yikes. I solved this by never exposing the STL types to managed C++.
In our experience, it is far better (if possible) to go C#->managed C++ wrapper->static library, if you have the ability to do that.