Подтвердить что ты не робот

Delphi StringBuilder

Существует в Delphi нечто вроде Java или С# StringBuilder? Или Delphi не нуждается в StringBuilder, а s := s + 'some string'; - хорошее выражение (в основном в for, while).

4b9b3361

Ответ 1

Да, Delphi предлагает TStringBuilder (начиная с версии 2009):

procedure TestStringBuilder;
var
  I: Integer;
  StringBuilder: TStringBuilder;
begin
  StringBuilder := TStringBuilder.Create;
  try
    for I := 1 to 10 do
    begin
      StringBuilder.Append('a string ');
      StringBuilder.Append(66); //add an integer
      StringBuilder.Append(sLineBreak); //add new line
    end;

    OutputWriteLine('Final string builder length: ' +
                    IntToStr(StringBuilder.Length));
  finally
    StringBuilder.Free;
  end;
end;

И да, вы правы. s := s + 'text'; на самом деле медленнее, чем использование TStringBuilder.

Ответ 2

В старшем Delphis вы можете использовать OmniThreadLibrary, например (вам понадобятся файлы HVStringBuilder.pas и HVStringData.pas).

Ответ 3

Delphi не " REQUIRE" класс строковых построителей, но он предоставляется для Delphi 2009, если вы так хотите его использовать. Ваш пример s: = s + 'некоторая строка'; является типичным методом конкатенирующих строк и используется в Паскале/Дельфи в течение последних нескольких десятилетий без каких-либо существенных проблем.

Ответ 4

Указанный TStringBuilder - это путь. В вашем конкретном случае конкатенация может быть прекрасной, но в любом случае я всегда старую альтернативу.

Я создаю файл xhtml содержимого содержимого EPUB в памяти (Delphi XE), и он так долго занимался его созданием, что я ни разу не позвонил ему (около 5 минут плюс перед отказом). Это пример реальной жизни, объединяющий около 800 000 символов текста. Принимая ТОЧНЫЙ такой же код и непосредственно заменяя инструкции стиля s: = s + '' с помощью операторов TStringBuilder.Append, он уменьшил его до 3 секунды. Чтобы повторить, не было никаких логических изменений за пределами перехода от конкатенации.

Ответ 5

Я перечислял некоторые полезные ресурсы в строках Delphi ниже.

Как сказал кто-то другой, простая конкатенация с использованием оператора "+" с типами строк общего назначения примерно такая же, как с помощью TStringbuilder (по крайней мере для операций вида:: = s + [...]]. Не знаю, правда ли это или нет, но производительность по крайней мере достаточно близка к тому, что [1], ниже, утверждает, что "Конкатенация строк в Delphi настолько быстро, что новый оптимизированный класс StringBuilder в Delphi 2009 не может победить". Это связано с тем, что строки модифицированы на месте, и Delphi transparententy выделяет больше памяти для базовой строки, если это необходимо, вместо того, чтобы выполнять операцию копирования на запись всех данных в новое место в памяти.

[1] http://blog.marcocantu.com/blog/delphi_super_duper_strings.html

[2] http://conferences.codegear.com/he/article/32120

[3] http://www.codexterity.com/delphistrings.htm

[4] http://www.monien.net/blog/index.php/2008/10/delphi-2009-tstringbuilder/

Ответ 6

s: = s + 'некоторая строка' может быть ужасно медленной, если вы делаете это в цикле из-за задействованного выделения памяти. У меня есть несколько тестов, которые показывают, что предварительное выделение памяти может быть в 132 раза быстрее (ДА ВЫ ЧИТАЕТЕ ПРАВО) быстрее !!!!

Код выглядит так:

 marker:= 1;
 CurBuffLen:= 0;
 for i:= 1 to Length(FileBody) DO
  begin
   if i > CurBuffLen then
    begin
     SetLength(s, CurBuffLen+ BuffSize);
     CurBuffLen:= Length(s)
    end;
   s[marker]:= FileBody[i];
   Inc(marker);
  end;

Смотрите мой ответ здесь для деталей: когда и почему я должен использовать TStringBuilder?

Примечание: мой код оптимизирован для

s: = s+ c

где c - символ, но вы можете легко адаптировать его

для s: = s + 'некоторая строка'

,

Ответ 7

Я действительно удивлен, что никто не упомянул ни в одном из комментариев или примеров, которые вы можете поручить TStringBuilder предварительно распределить буфер, соответствующий задаче во время создания экземпляра. Другими словами, если вы можете придумать простую оценку того, сколько памяти вам, вероятно, понадобится, немного поместите эту битку и используйте это значение для создания экземпляра TStringBuilder, вы избегаете перераспределения памяти, которые замедляют простую конкатенацию строк при сканировании:

buff := TStringBuilder.Create( tmpEstimatedSize );

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