mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-28 18:21:00 +02:00
* Faster DupeString by Rika. Fixes issue #39949
This commit is contained in:
parent
d5777174d8
commit
0b3c608d79
@ -1154,24 +1154,34 @@ end;
|
|||||||
function DupeString(const AText: string; ACount: Integer): string;
|
function DupeString(const AText: string; ACount: Integer): string;
|
||||||
|
|
||||||
var
|
var
|
||||||
Len: SizeInt;
|
Len, BitIndex, Rp: SizeInt;
|
||||||
Source, Target: PByte;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Len := Length(AText);
|
Len := Length(AText);
|
||||||
|
if (Len = 0) or (ACount <= 0) then
|
||||||
|
Exit('');
|
||||||
|
if ACount = 1 then
|
||||||
|
Exit(AText);
|
||||||
|
|
||||||
SetLength(Result, ACount * Len);
|
SetLength(Result, ACount * Len);
|
||||||
// Use PByte to skip implicit UniqueString, because SetLength always unique
|
Rp := 0;
|
||||||
Target := PByte(Result);
|
|
||||||
if Target = nil then // ACount = 0 or AText = ''
|
// Build up ACount repeats by duplicating the string built so far and adding another AText if corresponding ACount binary digit is 1.
|
||||||
Exit;
|
// For example, ACount = 5 = %101 will, starting from the empty string:
|
||||||
// Now ACount > 0 and Len > 0
|
// (1) duplicate (count = 0), add AText (count = 1)
|
||||||
Source := PByte(AText);
|
// (0) duplicate (count = 2)
|
||||||
repeat
|
// (1) duplicate (count = 4), add AText (count = 5)
|
||||||
Move(Source[0], Target[0], Len * SizeOf(Char));
|
for BitIndex := BsrDWord(ACount) downto 0 do
|
||||||
Inc(Target, Len * SizeOf(Char));
|
begin
|
||||||
Dec(ACount);
|
Move(Pointer(Result)^, PChar(Pointer(Result))[Rp], Rp * SizeOf(Char));
|
||||||
until ACount = 0;
|
Inc(Rp, Rp);
|
||||||
end;
|
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;
|
function ReverseString(const AText: string): string;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user