Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Quick padding of a string in Delphi

I was trying to speed up a certain routine in an application, and my profiler, AQTime, identified one method in particular as a bottleneck. The method has been with us for years, and is part of a "misc"-unit:

function cwLeftPad(aString:string; aCharCount:integer; aChar:char): string;
var
  i,vLength:integer;
begin
  Result := aString;
  vLength := Length(aString);
  for I := (vLength + 1) to aCharCount do    
    Result := aChar + Result;
end;

In the part of the program that I'm optimizing at the moment the method was called ~35k times, and it took a stunning 56% of the execution time!

It's easy to see that it's a horrible way to left-pad a string, so I replaced it with

function cwLeftPad(const aString:string; aCharCount:integer; aChar:char): string; 
begin
  Result := StringOfChar(aChar, aCharCount-length(aString))+aString;
end;

which gave a significant boost. Total running time went from 10,2 sec to 5,4 sec. Awesome! But, cwLeftPad still accounts for about 13% of the total running time. Is there an easy way to optimize this method further?

like image 830
Svein Bringsli Avatar asked Nov 05 '09 09:11

Svein Bringsli


1 Answers

This is my solution. I use StringOfChar instead of FillChar because it can handle unicode strings/characters:

function PadLeft(const Str: string; Ch: Char; Count: Integer): string;
begin
  if Length(Str) < Count then
  begin
    Result := StringOfChar(Ch, Count);
    Move(Str[1], Result[Count - Length(Str) + 1], Length(Str) * SizeOf(Char));
  end
  else Result := Str;
end;

function PadRight(const Str: string; Ch: Char; Count: Integer): string;
begin
  if Length(Str) < Count then
  begin
    Result := StringOfChar(Ch, Count);
    Move(Str[1], Result[1], Length(Str) * SizeOf(Char));
  end
  else Result := Str;
end;
like image 200
timidwolf25 Avatar answered Oct 08 '22 17:10

timidwolf25