2010-02-06 14 views
7

Angenommen, ich habe einen Zeiger vom Typ char * zu Unicode-String, und ich weiß, die Länge:Marshal.PtrToStringUni() vs neue String()?

char* _unmanagedStr; 
int _unmanagedStrLength; 

und ich habe 2 Möglichkeiten, es zu .NET-String zu konvertieren:

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

und

new string(_unmanagedStr, 0, _unmanagedStrLength); 

In meinen Tests, geben beiden Anrufe mir genau das gleiche Ergebnis, aber die new string() ist wie 1.8x mal schneller als Marshal.PtrToStringUni().

Warum ist dieser Leistungsunterschied? Gibt es einen weiteren funktionalen Unterschied zwischen den beiden?

Antwort

9

Gemessen aus verfügbarem Quellcode (Rotor) verwendet der System.String (Char *) -Konstruktor einen stark optimierten Codepfad durch CtorCharPtr(), es weist die Zeichenfolge FastAllocateString() zu. Marshal.PtrToStringUni() folgt einem völlig anderen Code-Pfad, es ist in C++ geschrieben und sieht so aus, als würde er die Zeichenfolge zweimal kopieren, ohne den Vorteil eines "schnellen Allokators".

Klar, nicht der gleiche Programmierer arbeitete daran. Fast sicher nicht einmal das selbe Team, da der Code einem anderen Programmiermodell entspricht. Der nächstliegende Manager war wahrscheinlich vier Stufen höher.

Nicht sicher, wie das hilfreich wäre, verwenden Sie die schnelle. Unglücke würden eine ähnliche Art von Ausnahme unter Windows erzeugen.

8

Die zweite ist nicht CLS-konform, erfordert unsicheren Code und kann unbestimmtes Verhalten haben, weshalb es wahrscheinlich schneller ist. Es gibt auch einen Bedarf an pin den Zeiger auf die nicht verwaltete Adresse oder der Garbage Collector könnte es neu zuweisen, was zu einem mehr überladenen Code führt. Wenn Sie nicht festgestellt haben, dass dies ein Engpass für Ihre Anwendung ist, werden Sie wahrscheinlich die Funktion PtrToStringUni verwenden wollen.