Marshal.PtrToStringUni() 与 new String()?

发布于 2024-08-20 15:58:48 字数 482 浏览 13 评论 0原文

假设我有一个 char* 类型的指向 unicode 字符串的指针,并且我知道长度:

char* _unmanagedStr;
int _unmanagedStrLength;

并且我有 2 种方法将其转换为 .NET 字符串:

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

并且

new string(_unmanagedStr, 0, _unmanagedStrLength);

在我的测试中,两个调用给出了完全相同的结果,但是 new string()Marshal.PtrToStringUni() 快 1.8 倍。

为什么会有这样的性能差异? 两者之间还有其他功能差异吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吾性傲以野 2024-08-27 15:58:48

从可用的源代码(Rotor)来看,System.String(Char*)构造函数通过CtorCharPtr()使用了经过高度优化的代码路径,它使用FastAllocateString()分配字符串。 Marshal.PtrToStringUni() 遵循完全不同的代码路径,它是用 C++ 编写的,看起来会复制字符串两次,而没有“快速分配器”的好处。

显然,不是同一个程序员在做这件事。几乎可以肯定,甚至不是同一个团队,因为代码适合不同的编程模型。最接近的共同点经理可能比他高四级。

不确定这会有什么帮助,请使用快速的。事故会在 Windows 上产生类似的异常。

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.

秋叶绚丽 2024-08-27 15:58:48

第二个不符合 CLS,需要不安全的代码,并且可能具有未确定的行为,这就是它可能更快的原因。还需要将指针固定非托管地址或垃圾收集器可能会重新分配它,这会导致代码更加混乱。除非您确定这是应用程序的瓶颈,否则您可能需要使用 PtrToStringUni 函数。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文