Вопрос

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

char* _unmanagedStr;
int _unmanagedStrLength;

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

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

и

new string(_unmanagedStr, 0, _unmanagedStrLength);

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

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

Это было полезно?

Решение

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

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

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

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top