Pergunta

Suponha que eu tenho um ponteiro do tipo char * a seqüência de caracteres Unicode, e eu sei que o comprimento:

char* _unmanagedStr;
int _unmanagedStrLength;

e eu tenho 2 maneiras de convertê-lo para string NET:

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

e

new string(_unmanagedStr, 0, _unmanagedStrLength);

Em meus testes, ambas as chamadas me dá exatamente o mesmo resultado, mas o new string() é como 1,8x vezes mais rápido que Marshal.PtrToStringUni().

Por que é que a diferença de desempenho? Existe alguma outra diferença funcional entre os dois?

Foi útil?

Solução

A julgar a partir do código fonte disponível (Rotor), o System.String (Char *) construtor usa um caminho de código altamente otimizado através CtorCharPtr (), atribui a string com FastAllocateString (). Marshal.PtrToStringUni () segue um caminho de código totalmente diferente, que é escrito em C ++ e parece ser copiar a cadeia duas vezes, sem o benefício de um "alocador rápido".

Claramente, não é o mesmo programador trabalhou sobre este assunto. Quase certamente nem mesmo a mesma equipe desde que o código se encaixa um modelo de programação diferente. O gerente mais próximo em comum era, provavelmente, quatro níveis acima.

Não tenho certeza como isso seria útil, use a um rápido. Percalços geraria um tipo semelhante de exceção no Windows.

Outras dicas

O segundo não é compatível com CLS, requer código inseguro e pode ter comportamento indeterminado e é por isso provavelmente é mais rápido. Há também uma necessidade de pin o ponteiro para o endereço não gerenciado ou o coletor de lixo pode realocá-lo que leades a um código mais desordenado. A menos que você determinou que este é um gargalo para a sua aplicação, você provavelmente vai querer usar o função PtrToStringUni .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top