Marshal.PtrToStringUni() vs new String()?
-
19-09-2019 - |
質問
Unicode 文字列への char* 型のポインターがあり、長さがわかっているとします。
char* _unmanagedStr;
int _unmanagedStrLength;
それを.NET文字列に変換するには2つの方法があります:
Marshal.PtrToStringUni((IntPtr)_unmanagedStr, _unmanagedStrLength);
そして
new string(_unmanagedStr, 0, _unmanagedStrLength);
私のテストでは、両方の呼び出しでまったく同じ結果が得られましたが、 new string()
よりも 1.8 倍ほど高速です Marshal.PtrToStringUni()
.
なぜそのようなパフォーマンスの違いがあるのでしょうか?両方の間に機能的な違いはありますか?
解決
利用可能なソースコード(ロータ)から判断すると、可能System.String(CHAR *)コンストラクタはCtorCharPtr()を介して高濃度最適化されたコード・パスを使用し、それは()FastAllocateString文字列を割り当てます。 Marshal.PtrToStringUni()は完全に異なるコードパスをたどるには、C ++で書かれている「高速アロケータ」の恩恵なしに、二回の文字列をコピーするように見える。
は明らかではなく、同じプログラマは、この上で働いていました。ほぼ確実にコードからいなくても同じチームには異なるプログラミングモデルに適合します。共通して最も近いマネージャは、おそらく4つのレベルアップだった。
それが参考になるかわからない、高速のいずれかを使用します。事故は、Windows上での例外の似たようなものを生成します。
他のヒント
2 番目の方法は CLS に準拠しておらず、安全でないコードが必要であり、動作が未確定である可能性があるため、おそらくこの方法の方が高速です。する必要もあります ピン アンマネージ アドレスへのポインタやガベージ コレクタがそのアドレスを再割り当てする可能性があり、コードがさらに乱雑になる可能性があります。これがアプリケーションのボトルネックであると判断しない限り、おそらく、 PtrToStringUni 関数。