7

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

char* _unmanagedStr;
int _unmanagedStrLength;

我有两种方法可以将其转换为 .NET 字符串:

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

new string(_unmanagedStr, 0, _unmanagedStrLength);

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

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

4

2 回答 2

9

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

显然,不是同一位程序员从事此工作。几乎可以肯定甚至不是同一个团队,因为代码适合不同的编程模型。最接近的共同经理可能是四个级别。

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

于 2010-02-06T17:26:38.847 回答
8

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

于 2010-02-06T17:09:41.103 回答