2010-02-06 23 views
7

Supongamos que tengo un puntero de tipo char * a cadena Unicode, y sé que la longitud:Marshal.PtrToStringUni() vs new String()?

char* _unmanagedStr; 
int _unmanagedStrLength; 

y tengo 2 maneras de convertir a cadena NET:

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

y

new string(_unmanagedStr, 0, _unmanagedStrLength); 

En mis pruebas, tanto las llamadas me da exactamente el mismo resultado, pero el new string() es como 1.8x veces más rápido que Marshal.PtrToStringUni().

¿Por qué es esa diferencia de rendimiento? ¿Hay alguna otra diferencia funcional entre los dos?

Respuesta

9

A juzgar por el código fuente disponible (Rotor), el constructor System.String (Char *) utiliza una ruta de código altamente optimizada a través de CtorCharPtr(), asigna la cadena con FastAllocateString(). Marshal.PtrToStringUni() sigue una ruta de código completamente diferente, está escrita en C++ y parece que va a copiar la cadena dos veces, sin el beneficio de un "rápido asignador".

Claramente, no el mismo programador trabajó en esto. Casi seguro que ni siquiera es el mismo equipo ya que el código se ajusta a un modelo de programación diferente. El gerente más cercano en común probablemente estaba cuatro niveles arriba.

No estoy seguro de cómo sería útil, use la rápida. Los contratiempos generarían un tipo similar de excepción en Windows.

8

El segundo no cumple con CLS, requiere un código inseguro y puede tener un comportamiento indeterminado, por lo que probablemente sea más rápido. También es necesario pin el puntero a la dirección no administrada o el recolector de basura podría reasignarlo lo que lleva a un código más desordenado. A menos que haya determinado que esto es un cuello de botella para su aplicación, es probable que desee utilizar la función PtrToStringUni.

Cuestiones relacionadas