7

ユニコード文字列へのchar*型のポインタがあり、長さがわかっているとします。

char* _unmanagedStr;
int _unmanagedStrLength;

そして私はそれを.NET文字列に変換する2つの方法があります:

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

new string(_unmanagedStr, 0, _unmanagedStrLength);

私のテストでは、どちらの呼び出しでもまったく同じ結果が得られますが、new string()はの1.8倍の速度ですMarshal.PtrToStringUni()

なぜそのパフォーマンスの違いがあるのですか?両者の間に別の機能的な違いはありますか?

4

2 に答える 2

9

利用可能なソース コード (Rotor) から判断すると、System.String(Char*) コンストラクターは、CtorCharPtr() を介して高度に最適化されたコード パスを使用し、FastAllocateString() で文字列を割り当てます。Marshal.PtrToStringUni() はまったく異なるコード パスに従います。これは C++ で記述されており、文字列を 2 回コピーしているように見えますが、「高速アロケータ」の利点はありません。

明らかに、同じプログラマーがこれに取り組んだわけではありません。コードが異なるプログラミング モデルに適合するため、ほぼ確実に同じチームでさえありません。共通の最も近いマネージャーは、おそらく 4 レベル上でした。

それがどのように役立つかわからない場合は、高速なものを使用してください。事故が発生すると、Windows で同様の種類の例外が生成されます。

于 2010-02-06T17:26:38.847 に答える
8

2 つ目は CLS に準拠しておらず、安全でないコードが必要であり、未確定の動作をする可能性があるため、おそらく高速です。また、ポインターをアンマネージ アドレスに固定する必要があります。そうしないと、ガベージ コレクターがそれを再割り当てして、コードがより複雑になる可能性があります。これがアプリケーションのボトルネックであると判断した場合を除き、おそらくPtrToStringUni関数を使用することをお勧めします。

于 2010-02-06T17:09:41.103 に答える