Marshal.PtrToStringUni() vs new String()?

假装没事ソ 提交于 2019-12-23 08:47:10

问题


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?


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/2213871/marshal-ptrtostringuni-vs-new-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!