Recent

Author Topic: Any TStringBuilder class implementation?  (Read 24477 times)

Thaddy

  • Hero Member
  • *****
  • Posts: 18711
  • To Europe: simply sell USA bonds: dollar collapses
Re: Any TStringBuilder class implementation?
« Reply #30 on: January 10, 2026, 03:43:23 pm »
Did you all miss:
https://www.freepascal.org/docs-html/rtl/sysutils/tstringbuilder.html
https://www.freepascal.org/daily/doc/rtl/sysutils/tunicodestringbuilder.html
https://www.freepascal.org/daily/doc/rtl/sysutils/tansistringbuilder.html

I hope Micheal does it not take too seriously that you did read the official documentation?

This has already been solved over 12 years ago.
If there are still things missing, the way to go is a feature request.
« Last Edit: January 10, 2026, 03:47:28 pm by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

bytebites

  • Hero Member
  • *****
  • Posts: 776
Re: Any TStringBuilder class implementation?
« Reply #31 on: January 11, 2026, 08:47:34 am »
Stringbuilder.append(char) is slower than naive string concatenation.

BeniBela

  • Hero Member
  • *****
  • Posts: 954
    • homepage
Re: Any TStringBuilder class implementation?
« Reply #32 on: January 11, 2026, 09:33:44 am »
Stringbuilder.append(char) is slower than naive string concatenation.
that is why I wrote my own string builder

Thaddy

  • Hero Member
  • *****
  • Posts: 18711
  • To Europe: simply sell USA bonds: dollar collapses
Re: Any TStringBuilder class implementation?
« Reply #33 on: January 11, 2026, 09:50:08 am »
Stringbuilder.append(char) is slower than naive string concatenation.
Even if the capacity is properly set? I did not notice that yet.
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

bytebites

  • Hero Member
  • *****
  • Posts: 776
Re: Any TStringBuilder class implementation?
« Reply #34 on: January 11, 2026, 02:09:21 pm »
Stringbuilder.append(char) is slower than naive string concatenation.
Even if the capacity is properly set? I did not notice that yet.
It is not relevant.

Thaddy

  • Hero Member
  • *****
  • Posts: 18711
  • To Europe: simply sell USA bonds: dollar collapses
Re: Any TStringBuilder class implementation?
« Reply #35 on: January 11, 2026, 02:21:10 pm »
It is not relevant.
Really? Setting the capacity is really relevant for the performance of all Tstringbuilders, even on Delphi, where it is even documented as such.
It avoids re-allocations and that is where the perceived speed loss comes from.
The default capacity is rather low / non-existent.
Note I did not test it thoroughly yet, but it seems there is a considerable performance gain compared to the default when I set it to about 1024 even for longer strings (because the growth factor relies on the initial value).

If you think it is not relevant, please give an example?
« Last Edit: January 11, 2026, 02:28:28 pm by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

bytebites

  • Hero Member
  • *****
  • Posts: 776
Re: Any TStringBuilder class implementation?
« Reply #36 on: January 11, 2026, 03:03:28 pm »
It is not relevant.
Really? Setting the capacity is really relevant for the performance of all Tstringbuilders, even on Delphi, where it is even documented as such.
It avoids re-allocations and that is where the perceived speed loss comes from.
The default capacity is rather low / non-existent.
Note I did not test it thoroughly yet, but it seems there is a considerable performance gain compared to the default when I set it to about 1024 even for longer strings (because the growth factor relies on the initial value).

If you think it is not relevant, please give an example?
Since the problem is poor algorithm for char type.

Thaddy

  • Hero Member
  • *****
  • Posts: 18711
  • To Europe: simply sell USA bonds: dollar collapses
Re: Any TStringBuilder class implementation?
« Reply #37 on: January 11, 2026, 03:15:48 pm »
Since the problem is poor algorithm for char type.
Examine the sourcecode: it is not poor, it relies on the buffersize. As it should.
I asked for an example.
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

ALLIGATOR

  • Sr. Member
  • ****
  • Posts: 334
  • I use FPC [main] 💪🐯💪
Re: Any TStringBuilder class implementation?
« Reply #38 on: January 11, 2026, 03:28:11 pm »
Code: Pascal  [Select][+][-]
  1. program app;
  2. {$mode objfpc}{$h+}
  3.  
  4. uses SysUtils, DateUtils;
  5.  
  6. const
  7.   mem = 4*1024*1024;
  8.  
  9. var
  10.   sb: TStringBuilder;
  11.   t: TDateTime;
  12.   i, j: Integer;
  13.   r, s: AnsiString;
  14.  
  15. begin
  16.   t:=Now;
  17.   for i:=1 to 100 do
  18.   begin
  19.     r:='';
  20.     s:=StringOfChar('*', i);
  21.     for j:=1 to mem div i do
  22.       r:=r+s;
  23.   end;
  24.   WriteLn('concat: ', MilliSecondsBetween(Now, t));
  25.  
  26.   t:=Now;
  27.   sb:=TStringBuilder.Create;
  28.   for i:=1 to 100 do
  29.   begin
  30.     sb.Length:=1;
  31.     sb.Capacity:=1;
  32.     s:=StringOfChar('*', i);
  33.     for j:=1 to mem div i do
  34.       sb.Append(s);
  35.   end;
  36.   r:=sb.ToString;
  37.   sb.Free;
  38.   WriteLn('sb: ', MilliSecondsBetween(Now, t));
  39.  
  40.   ReadLn;
  41. end.

Code: Pascal  [Select][+][-]
  1. concat: 3206
  2. sb: 382
I may seem rude - please don't take it personally

bytebites

  • Hero Member
  • *****
  • Posts: 776
Re: Any TStringBuilder class implementation?
« Reply #39 on: January 11, 2026, 03:30:26 pm »
Test program for a person, who unable to test thoroughly.

Code: Pascal  [Select][+][-]
  1. program app;
  2. {$mode objfpc}{$h+}
  3.  
  4. uses SysUtils, DateUtils;
  5.  
  6. const
  7.   c = 10000000;
  8.  
  9. var
  10.   sb: TStringBuilder;
  11.   t: TDateTime;
  12.   i: Integer;
  13.   r: AnsiString;
  14.  
  15. begin
  16.   t:=Now;
  17.   r:='';
  18.   for i:=1 to c do
  19.       r:=r+'e';
  20.  
  21.   WriteLn('concat: ', MilliSecondsBetween(Now, t));
  22.  
  23.   t:=Now;
  24.   sb:=TStringBuilder.Create;
  25.   //sb:=TStringBuilder.Create(c);
  26.   for i:=1 to c do
  27.       sb.Append('e');
  28.   WriteLn('sb: ', MilliSecondsBetween(Now, t));
  29.   sb.Free;
  30.  
  31. end.
« Last Edit: January 11, 2026, 03:37:46 pm by bytebites »

Thaddy

  • Hero Member
  • *****
  • Posts: 18711
  • To Europe: simply sell USA bonds: dollar collapses
Re: Any TStringBuilder class implementation?
« Reply #40 on: January 11, 2026, 03:47:42 pm »
Please write correct code and start timing correctly:
Code: Pascal  [Select][+][-]
  1. program app;
  2. {$mode objfpc}{$h+}
  3.  
  4. uses SysUtils, DateUtils;
  5.  
  6. const
  7.   c = 10000000;
  8.  
  9. var
  10.   sb: TStringBuilder;
  11.   t: TDateTime;
  12.   i: Integer;
  13.   r: AnsiString;
  14.  
  15. begin
  16.   r:='';
  17.   t:=Now;
  18.   for i:=1 to c do
  19.       r:=r+'e';
  20.  
  21.   WriteLn('concat: ', MilliSecondsBetween(Now, t));
  22.  
  23.   sb:=TStringBuilder.Create; // default capacity used
  24.   t:=Now;
  25.   for i:=1 to c do
  26.       sb.Append('e');
  27.   WriteLn('sb: ', MilliSecondsBetween(Now, t));
  28.   sb.Free;
  29.  
  30. end.
Sb is faster.
« Last Edit: January 11, 2026, 03:51:20 pm by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

bytebites

  • Hero Member
  • *****
  • Posts: 776
Re: Any TStringBuilder class implementation?
« Reply #41 on: January 11, 2026, 03:57:52 pm »
Code: Pascal  [Select][+][-]
  1. program app;
  2. {$mode objfpc}{$h+}
  3.  
  4. uses SysUtils, DateUtils;
  5.  
  6. const
  7.   c = 10000000;
  8.  
  9. var
  10.   sb: TStringBuilder;
  11.   t: TDateTime;
  12.   i: Integer;
  13.   r: AnsiString;
  14.  
  15. begin
  16.   t:=Now;
  17.   r:='';
  18.   for i:=1 to c do
  19.       r:=r+'e';
  20.  
  21.   WriteLn('concat: ', MilliSecondsBetween(Now, t));
  22.  
  23.   t:=Now;
  24.   sb:=TStringBuilder.Create; // default capacity used
  25.   for i:=1 to c do
  26.       sb.Append('e');
  27.   WriteLn('sb default: ', MilliSecondsBetween(Now, t));
  28.   sb.Free;
  29.  
  30.   t:=Now;
  31.   sb:=TStringBuilder.Create(c);
  32.   for i:=1 to c do
  33.       sb.Append('e');
  34.   WriteLn('sb: no realloc ', MilliSecondsBetween(Now, t));
  35.   sb.Free;
  36.  
  37. end.
Quote
concat: 130
sb default: 352
sb: no realloc 347
How is with the capacity issue?
« Last Edit: January 11, 2026, 03:59:48 pm by bytebites »

Thaddy

  • Hero Member
  • *****
  • Posts: 18711
  • To Europe: simply sell USA bonds: dollar collapses
Re: Any TStringBuilder class implementation?
« Reply #42 on: January 11, 2026, 04:05:44 pm »
Well, try  :o ;)
Whatever the tries: there is no difference or SB wins in most cases.
« Last Edit: January 11, 2026, 04:13:50 pm by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

bytebites

  • Hero Member
  • *****
  • Posts: 776
Re: Any TStringBuilder class implementation?
« Reply #43 on: January 11, 2026, 04:34:13 pm »
Well, try  :o ;)
Whatever the tries: there is no difference or SB wins in most cases.

Didn't you see the results? You claimed that there is some difference due capacity.

Sb should win always.

ALLIGATOR

  • Sr. Member
  • ****
  • Posts: 334
  • I use FPC [main] 💪🐯💪
Re: Any TStringBuilder class implementation?
« Reply #44 on: January 11, 2026, 04:40:57 pm »
Sb should win always.

Code: Pascal  [Select][+][-]
  1. program app;
  2. {$mode objfpc}{$h+}
  3.  
  4. uses SysUtils, DateUtils;
  5.  
  6. const
  7.   c = 10000000;
  8.  
  9. var
  10.   sb: TStringBuilder;
  11.   t: TDateTime;
  12.   i: Integer;
  13.   r: AnsiString;
  14.  
  15. begin
  16.   t:=Now;
  17.   r:='';
  18.   for i:=1 to c do
  19.       r:=r+AnsiString('e');
  20.  
  21.   WriteLn('concat: ', MilliSecondsBetween(Now, t));
  22.  
  23.   t:=Now;
  24.   sb:=TStringBuilder.Create; // default capacity used
  25.   for i:=1 to c do
  26.       sb.Append(AnsiString('e'));
  27.   WriteLn('sb default: ', MilliSecondsBetween(Now, t));
  28.   sb.Free;
  29.  
  30.   t:=Now;
  31.   sb:=TStringBuilder.Create(c);
  32.   for i:=1 to c do
  33.       sb.Append(AnsiString('e'));
  34.   WriteLn('sb: no realloc ', MilliSecondsBetween(Now, t));
  35.   sb.Free;
  36. end.

And that's how it is )

Code: Pascal  [Select][+][-]
  1. concat: 406
  2. sb default: 118
  3. sb: no realloc 112
I may seem rude - please don't take it personally

 

TinyPortal © 2005-2018