views:

204

answers:

2

Suppose i have a pointer of type char* to unicode string, and i know the length:

char* _unmanagedStr;
int _unmanagedStrLength;

and i have 2 ways to convert it to .NET string:

Marshal.PtrToStringUni((IntPtr)_unmanagedStr, _unmanagedStrLength);

and

new string(_unmanagedStr, 0, _unmanagedStrLength);

In my tests, both calls gives me exactly the same result, but the new string() is like 1.8x times faster than Marshal.PtrToStringUni().

Why is that performance difference? Is there any another functional difference between the both?

+7  A: 

The second is not CLS compliant, requires unsafe code and might have undetermined behavior which is why probably it's faster. There's also a need to pin the pointer to the unmanaged address or the garbage collector might reallocate it which leades to a more cluttered code. Unless you've determined that this is a bottleneck for your application you'll probably want to use the PtrToStringUni function.

Darin Dimitrov
+4  A: 

Judging from available source code (Rotor), the System.String(Char*) constructor uses a heavily optimized code path through CtorCharPtr(), it allocates the string with FastAllocateString(). Marshal.PtrToStringUni() follows an entirely different code path, it is written in C++ and looks to be copying the string twice, without the benefit of a "fast allocator".

Clearly, not the same programmer worked on this. Almost certainly not even the same team since the code fits a different programming model. The closest manager in common was probably four levels up.

Not sure how that would be helpful, use the fast one. Mishaps would generate a similar kind of exception on Windows.

Hans Passant