2013-08-15 4 views
5

мне очень интересно, что происходит с этим фрагментом кода в Delphi 2010:UnicodeString к Добавление данных WideString в Delphi

function foo: WideString; 
var 
    myUnicodeString: UnicodeString; 
begin 
    for i:=1 to 1000 do 
    begin 
    myUnicodeString := ... something ...; 

    result := result + myUnicodeString; // This is where I'm interested 
    end; 
end; 

Сколько преобразования строк участвуют, и какие-либо особенно плохо производительность мудрым?

Я знаю, что функция должна просто вернуть UnicodeString, но я видел этот анти-шаблон в потоковом коде VCL и хочу понять этот процесс.

+0

Вы пытались посмотреть это в окне процессора отладчика? – OnTheFly

+0

@OnTheFly: На самом деле это часть проекта C++ Builder, и по какой-то причине BCB2010 не любит устанавливать точки останова в коде VCL ... Я попробую переступить еще кое-что. – Roddy

+0

Если у вас нет Delphi для изучения сгенерированного кода для вашего тезиса, я могу опубликовать разборку, но я действительно не уверен, как представить его в полезной форме ... – OnTheFly

ответ

8

Чтобы ответить на ваш вопрос о том, что код на самом деле делает, это утверждение:

result := result + myUnicodeString; 

ли следующее:

  1. вызовы System._UStrFromWStr() преобразовать Result к температуре UnicodeString

  2. вызывает System._UStrCat(), чтобы объединить myUnicodeString на t emp

  3. вызывает System._WStrFromUStr(), чтобы преобразовать температуру в WideString и назначить ее обратно Result.

Существует System._WStrCat() функция для конкатенации с WideString на WideStringSystem._UStrCat() для UnicodeString). Если бы CodeGear/Embarcadero был умнее об этом, они могли бы реализовать перегрузку System._WStrCat(), которая принимает вход UnicodeString и WideString в качестве выхода (и наоборот для объединения WideString на UnicodeString). Таким образом, никакие временные преобразования UnicodeString больше не нужны. Оба WideString и UnicodeString кодируются как UTF-16 (в основном, но я не буду вдаваться в это здесь), поэтому объединение их вместе - это всего лишь одно выделение и перемещение, как при объединении двух UnicodeString s или двух WideString вместе.

+0

Спасибо Remy. Это объясняет много! – Roddy

+0

+1 для анализа, который я не смог предоставить –

4

Производительность плохая. Нет необходимости в каких-либо преобразованиях кодировки, поскольку все кодируется UTF-16. Тем не менее, WideString - это оболочка типа COM BSTR, которая работает хуже, чем собственный UnicodeString.

Естественно, вы должны предпочесть выполнять всю свою работу с родными типами: UnicodeString или TStringBuilder и конвертировать в WideString в последний момент.

Это, как правило, хорошая политика. Вы не хотите использовать WideString внутренне, потому что это чисто тип взаимодействия. Так что только конвертировать в (и из) WideString на границе взаимодействия.

+0

Спасибо.Мне особенно любопытно, будет ли строка concat (wide: = wide + uni) в юникоде или в широком домене. Если это unicode, то задействуются два преобразования. (широкий-> uni, concat, uni-> wide) – Roddy

+0

Я не знаю, что конкретная деталь с головы. Но тривиально легко работать с отладчиком. Что-то у меня сейчас нет. В любом случае, вы не хотите этого. Выполняйте всю свою работу с TStringBuilder и конвертируйте в WideString как можно позже. Все эти конкатенации были бы плохими даже с чистыми родными струнами. Тяжело на куче. –

+0

Это не мой код. Он находится в классах.pas в D2010 (CombineWideString). У меня возникла проблема, когда форма с единственным строковым свойством 4 МБ (да, но есть веская причина!) Потребовалось 2,5 минуты (!) Для загрузки при использовании текстовых DFM, а под вторым - с двоичным. – Roddy

 Смежные вопросы

  • Нет связанных вопросов^_^