Который берет наибольший успех: AnsiString для String или String для AnsiString? - PullRequest
1 голос
/ 13 октября 2011

Для моих целей я действительно использую символьные данные ASCII (для отправки текстовых файлов ASCII в состояние), поэтому простое использование unicodestring не поможет конечному результату (мне все равно придется что-то преобразовывать).

У меня есть возможность преобразовать функцию StrComp в Delphi 2009, которая пошла от сравнения AnsiString и PAnsiChar в UnicodeString и PAnsiChar.

Val : PAnsiChar
Mask : TEditMask;

....

это мой оригинальный код, это не хорошо

StrComp(PAnsiChar(Mask.EditText), Val);

....

Итак, я могу изменить это на:

StrComp(PAnsiChar(AnsiString(MAskEdit.EditText), Val);

или, я могу изменить это на это (дополнительные преобразования для «ясности»):

StrComp(PChar(MAskEdit.EditText), PChar(String(AnsiString(Val))));

Я помню, как Марко Канту говорил: не делай одного из них в цикле, я просто не помню, какой или почему.

Ответы [ 2 ]

5 голосов
/ 14 октября 2011

Если вы скомпилируете это:

StrComp(PAnsiChar(Mask.EditText), Val);

Существует неявное преобразование из Mask.EditText как UnicodeString во временное AnsiString, чтобы разрешить приведение типа к PAnsiChar.Это ваша вторая строка:

StrComp(PAnsiChar(AnsiString(MAskEdit.EditText), Val);

Но запись

StrComp(PChar(MAskEdit.EditText), PChar(String(AnsiString(Val))));

позволит PChar(MAskEdit.EditText) вернуть PChar, то есть PWideChar, поэтому он будет использовать другойперегруженная StrComp функция.

На самом деле, с Delphi 2009 в SysUtils.pas определены две перегруженные функции:

function StrComp(const Str1, Str2: PAnsiChar): Integer; overload;
function StrComp(const Str1, Str2: PWideChar): Integer; overload;

Обе функции не будут вызывать Windows API, но будутсравнивайте символы один за другим с учетом регистра.

Так что я советую вам просто не использовать указатель в вашем коде, а полагаться на простые string = UnicodeString переменные везде в вашем коде,и вместо этого используйте эту функцию:

function CompareStr(const S1, S2: string): Integer;

Сравнение будет таким же, и скрытого преобразования не будет.Проблема с WideChar вместо AnsiChar (т. Е. С наличием в два раза больше памяти) ничто по сравнению с преобразованием (два вызова WinAPI) между юникодом и текущей страницей ANSI.Чтобы процитировать ваш заголовок, направление конверсии не имеет значения: оно всегда намного медленнее, чем без конвертации.

Если вы ищете скорость, я подозреваю, что Mask.EditText определенно является узким местом в вашем коде.Этот метод отправит сообщение GDI, дождется ответа компонента, а затем повлияет на текст string.Вам лучше использовать временную переменную в стеке, если, как я подозреваю, вы используете это Mask.EditText выражение в цикле.

2 голосов
/ 14 октября 2011

Реальный вопрос - почему вы сравниваете UnicodeString с PAnsiChar вместо обновления данных PAnsiChar в Unicode? Вы должны использовать AnsiChar / AnsiString на границах, которые взаимодействуют с устаревшими данными, сетевыми подключениями и т. Д. Вся внутренняя обработка должна использовать одностроковое кодирование, чтобы избежать подобных проблем. Преобразуйте устаревшие / сетевые данные из Ansi в Unicode при загрузке данных. Конвертировать из Unicode в Ansi при сохранении устаревших данных, отправке сетевых данных и т. Д.

...