* Faster DupeString by Rika. Fixes issue #39949

This commit is contained in:
Michaël Van Canneyt 2022-10-13 13:00:57 +02:00
parent d5777174d8
commit 0b3c608d79

View File

@ -1154,24 +1154,34 @@ end;
function DupeString(const AText: string; ACount: Integer): string;
var
Len: SizeInt;
Source, Target: PByte;
Len, BitIndex, Rp: SizeInt;
begin
Len := Length(AText);
if (Len = 0) or (ACount <= 0) then
Exit('');
if ACount = 1 then
Exit(AText);
SetLength(Result, ACount * Len);
// Use PByte to skip implicit UniqueString, because SetLength always unique
Target := PByte(Result);
if Target = nil then // ACount = 0 or AText = ''
Exit;
// Now ACount > 0 and Len > 0
Source := PByte(AText);
repeat
Move(Source[0], Target[0], Len * SizeOf(Char));
Inc(Target, Len * SizeOf(Char));
Dec(ACount);
until ACount = 0;
end;
Rp := 0;
// Build up ACount repeats by duplicating the string built so far and adding another AText if corresponding ACount binary digit is 1.
// For example, ACount = 5 = %101 will, starting from the empty string:
// (1) duplicate (count = 0), add AText (count = 1)
// (0) duplicate (count = 2)
// (1) duplicate (count = 4), add AText (count = 5)
for BitIndex := BsrDWord(ACount) downto 0 do
begin
Move(Pointer(Result)^, PChar(Pointer(Result))[Rp], Rp * SizeOf(Char));
Inc(Rp, Rp);
if ACount shr BitIndex and 1 <> 0 then
begin
Move(Pointer(AText)^, PChar(Pointer(Result))[Rp], Len * SizeOf(Char));
Inc(Rp, Len);
end;
end;
end;
function ReverseString(const AText: string): string;