Маршал. PtrToStringUni () по сравнению с новой Строкой ()?

Предположим, что у меня есть указатель символа типа* к строке unicode, и я знаю длину:

char* _unmanagedStr;
int _unmanagedStrLength;

и у меня есть 2 способа преобразовать его в строку.NET:

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

и

new string(_unmanagedStr, 0, _unmanagedStrLength);

В моих тестах оба вызова дают мне точно тот же результат, но new string() похож 1.8x времена быстрее, чем Marshal.PtrToStringUni().

Почему то различие в производительности? Есть ли между обоими какое-либо другое функциональное различие?

7
задан Kate Gregory 21 June 2010 в 13:32
поделиться

2 ответа

Судя по доступному исходному коду (Rotor), конструктор System.String (Char *) использует сильно оптимизированный путь кода через CtorCharPtr (), он выделяет строка с FastAllocateString (). Marshal.PtrToStringUni () следует совершенно по другому пути кода, он написан на C ++ и, похоже, дважды копирует строку без преимущества «быстрого распределителя».

Ясно, что над этим работал не один и тот же программист. Почти наверняка даже не одна и та же команда, поскольку код соответствует другой модели программирования. Ближайший из общих менеджеров, вероятно, был на четыре уровня выше.

Не уверен, насколько это будет полезно, воспользуйтесь быстрым. В Windows может возникнуть подобное исключение.

9
ответ дан 6 December 2019 в 11:49
поделиться

Второй несовместим с CLS, требует небезопасного кода и может иметь неопределенное поведение, поэтому, вероятно, он быстрее. Также необходимо закрепить указатель на неуправляемый адрес, иначе сборщик мусора может перераспределить его, что приведет к более загроможденному коду. Если вы не определили, что это узкое место для вашего приложения, вы, вероятно, захотите использовать функцию PtrToStringUni .

8
ответ дан 6 December 2019 в 11:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: