Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fast way to split a string into fixed-length parts in Delphi

I need to split a string to a TStringList with fixed-length sub-strings.

Currently I use:

procedure StrToStringList(ASource: string; AList: TStrings; AFixedLen: Integer);
begin
    Assert(Assigned(AList));
    while Length(ASource) > AFixedLen do
    begin
        AList.Add(LeftStr(ASource, AFixedLen));
        Delete(ASource, 1, AFixedLen);
    end;
    AList.Add(ASource);
end;

This works, but seems to be slow. Any better / faster idea?

Edited: Profiling of the results:

The speed gain is quite impressive. Here are the results of my (subjective) profiling.

Data size: 290KB, FixedLen: 100:

  • Original code: 58 ms
  • Heffernan: 1 ms
  • Deltics: 1 ms

Data size: 2805KB, FixedLen: 100:

  • Original code: 5803 ms
  • Heffernan: 5 ms
  • Deltics: 4 ms
like image 586
Alois Heimer Avatar asked Dec 09 '22 02:12

Alois Heimer


1 Answers

I think it is wasteful to modify the input string. Avoid this like this:

var
  Remaining: Integer;
  StartIndex: Integer;
begin
  Remaining := Length(ASource);
  StartIndex := 1;
  while Remaining > 0 do
  begin
    AList.Add(Copy(ASource, StartIndex, AFixedLen));
    inc(StartIndex, AFixedLen);
    dec(Remaining, AFixedLen);
  end;
end;

This will reduce the amount of heap allocation, and the copying.

However, I would not be surprised if you observed little gain in performance. In order to perform any serious optimisation we'd likely need to see some example input data.

like image 156
David Heffernan Avatar answered May 13 '23 11:05

David Heffernan