Delphi StringBuilder

白昼怎懂夜的黑 提交于 2020-01-31 06:18:47

问题


Exists in Delphi something like the Java or C# StringBuilder? Or Delphi does not need StringBuilder and s := s + 'some string'; is good expression (mainly in for, while loops).


回答1:


Yes, Delphi offers TStringBuilder (since version 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;

And yes, you are right. s := s + 'text'; isn't really slower than using TStringBuilder.




回答2:


In older Delphis, you can use Hallvard Vassbotn's HVStringBuilder. I failed to find the sources on his blog, but you can fetch them in the OmniThreadLibrary source tree, for example (you'll need files HVStringBuilder.pas and HVStringData.pas).




回答3:


Delphi does not "REQUIRE" a string builder class, but one is provided for Delphi 2009 if you so desire to use it. Your example of s := s + 'some string'; is a typical method of concatinating strings and has been used in Pascal/Delphi for the past few decades without any significant problems.




回答4:


The TStringBuilder mentioned is the way to go. In your specific case concatenation may be fine, but I'd always try the alternative anyway.

I am creating an EPUB body content xhtml file in memory (Delphi XE) and it was taking so long to produce it that I never once let it finish (about 5 minutes plus before abandoning). This is a real life example combining around 800,000 characters of text. Taking the EXACT same code and directly replacing the s:=s+'' style statements with TStringBuilder.Append statements reduced it to around 3 seconds. To reiterate, there were no logic changes beyond a switch away from concatenation.




回答5:


I've listed some good resources on Delphi strings below.

As someone else said, simple concatenation using the '+' operator with the general purpose string types is about as fast as using TStringbuilder (at least for operations of the form: 's := s + [. . . ]'). Don't know if it's true or not, but performance is at least close enough that [1], below, asserts that "Strings concatenation in Delphi is so fast that the new optimized StringBuilder class in Delphi 2009 cannot beat it." This is because the strings are modified in place and Delphi transparenty allocates more memory for the base string if needed, rather than doing a copy-on-write operation of all the data to a new location in memory.

[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:


I'm really surprised that no one mentioned in any of the comments or examples that you can instruct TStringBuilder to preallocate a buffer appropriate to the task during instantiation. In other words, if you can come up with a simple estimate of how much memory you'll probably need, pad that a bit, and use that value to instantiate TStringBuilder , you avoid the memory reallocations that slow simple string concatenation to a crawl:

buff := TStringBuilder.Create( tmpEstimatedSize );

I use TStringBuilder regularly in new code and to optimize old code, and the CPU savings when building large strings incrementally is dramatic. Now to be transparent, if I just have a handful of strings to concatenate, I don't bother with TStringBuilder. But if I'm, say, serializing what could potentially be a large amount of data, TStringBuilder is the obvious solution.




回答7:


s := s + 'some string' could be terribly slow if you do it in a loop because of the memory allocation involved. I have dome some tests that show that preallocating memory could be 132 times (YES YOU READ IT RIGHT) faster!!!!

The code is like this:

 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;

See my answer here for details: When and Why Should I Use TStringBuilder?

Note: my code is optimized for

s:= s+ c

where c is a char, but you can easily adapt it

for s:= s + 'some string'

.



来源:https://stackoverflow.com/questions/686413/delphi-stringbuilder

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!