Q:

Delphi (10.2): fast Integer conversion to string with separator

Let's say we have this Integer 1234567890, we want it converted to a string with a separator = 1.234.567.890, we could do Format('%n',[1234567890.0]); but it's very slow. I wrote a function to speed it up considerably (more than 2x faster). How could I improve it further, or can you come up with a faster routine?
function MyConvertDecToStrWithDot(Const n: UInt64): string;
Var a,b,x: Integer;
    z,step: Integer;
    l: SmallInt;
begin
  Result := IntToStr(n);
  if n < 1000 then Exit;

  l := Length(Result);
  a := l div 3;
  b := l mod 3;
  step := b+1;

  z := 4;
  if b <> 0 then begin
    Insert('.',Result,step);
    Inc(z,step);
  end;
  for x := 1 to (a-1) do begin
    Insert('.',Result,z);
    Inc(z,4);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
Var a: Integer;
    s: string;
begin
  PerfTimerInit;
  for a := 1 to 1000000 do
   s := MyConvertDecToStrWithDot(1234567890);
  Memo1.lines.Add(PerfTimerStopMS.ToString);
  caption := s;
end;

32-bit

Format: ~230ms
  My function: ~79ms

64-bit

Format: ~440ms
  My function: ~103ms

A:

In my tests, the following is ever so slightly faster:
function ThousandsSepStringOf(Num: UInt64): string;
const
  MaxChar = 30; // Probably, 26 is enough: 19 digits + 7 separators
var
  Count: Integer;
  Rem: UInt64;
  Res: array[0..MaxChar] of Char;
  WritePtr: PChar;
begin
  WritePtr := @Res[MaxChar];
  WritePtr^ := #0;
  Count := 0;
  while Num > 0 do
  begin
    DivMod(Num, 10, Num, Rem);
    Dec(WritePtr);
    WritePtr^ := Char(Byte(Rem) + Ord('0'));
    Inc(Count);
    if Count = 3 then
    begin
      Dec(WritePtr);
      WritePtr^ := '.';
      Count := 0;
    end;
  end;
  if WritePtr^ = '.' then
    Inc(WritePtr);
  Count := MaxChar - ((NativeInt(WritePtr) - NativeInt(@Res)) shr 1);
  SetLength(Result, Count);
  Move(WritePtr^, PByte(Result)^, Count * SizeOf(Char));
end;

Tested with:
procedure TestHisCode;
Var
  a: Integer;
  s: string;
  SW: TStopwatch;
begin
  Writeln('His code');
  SW := TStopwatch.StartNew;
  for a := 1 to KLoops do
    s := MyConvertDecToStrWithDot(1234567890);
  Writeln(SW.ElapsedMilliseconds);
  Writeln(s);
  Writeln;
end;

procedure TestMyCode;
Var
  a: Integer;
  s: string;
  SW: TStopwatch;
begin
  Writeln('My code');
  SW := TStopwatch.StartNew;
  for a := 1 to KLoops do
    s := ThousandsSepStringOf(1234567890);
  Writeln(SW.ElapsedMilliseconds);
  Writeln(s);
  Writeln;
end;

and:
  TestHisCode;
  TestMyCode;
  TestMyCode;
  TestHisCode;
  TestMyCode;
  TestHisCode;
  TestHisCode;
  TestMyCode;

