[fpc-devel] "Blank slate" next version of FPC
Benito van der Zander
benito at benibela.de
Sat Feb 23 01:17:29 CET 2019
Hi,
> The trick with enumerators is to never make them classes, and use
> advanced records instead, I've found. This way you avoid the heap
> allocation and the implicit try/finally. Also make sure you inline the
> MoveNext and GetCurrent!
that's what I do.
But the generated assembly is still worse than an old for loop, because
it keeps all the fields of the record in memory.
for example
> for I in TSlice<SizeUInt>.TakeWhile(Arr, Test) do J := I;
generates something like this
0000000000401290 488b45f0 mov -0x10(%rbp),%rax
0000000000401294 488b00 mov (%rax),%rax
0000000000401297 488905b22a0300 mov %rax,0x32ab2(%rip)
# 0x433d50 <U_$P$PROJECT1_$$_I>
project1.lpr:75 J := I;
000000000040129E 488905bb2a0300 mov %rax,0x32abb(%rip)
# 0x433d60 <U_$P$PROJECT1_$$_J>
project1.lpr:74 for I in
TSlice<SizeUInt>.TakeWhile(Arr, Test) do
00000000004012A5 488345f008 addq $0x8,-0x10(%rbp)
project1.lpr:69 begin
00000000004012AA 488b45e8 mov -0x18(%rbp),%rax
project1.lpr:74 for I in
TSlice<SizeUInt>.TakeWhile(Arr, Test) do
00000000004012AE 483b45f0 cmp -0x10(%rbp),%rax
00000000004012B2 720a jb 0x4012be <main+334>
00000000004012B4 483b45e0 cmp -0x20(%rbp),%rax
00000000004012B8 7404 je 0x4012be <main+334>
00000000004012BA b001 mov $0x1,%al
00000000004012BC eb02 jmp 0x4012c0 <main+336>
00000000004012BE 30c0 xor %al,%al
00000000004012C0 84c0 test %al,%al
00000000004012C2 75cc jne 0x401290 <main+288>
Nearly every line is accessing some memory, when it could keep
everything in a few registers. amd64 has 16 registers, but fpc seems to
only know three when records are involved
Cheers,
Benito
Am 22.02.19 um 16:51 schrieb Ben Grasset:
> On Fri, Feb 22, 2019 at 1:07 AM Paul van Helden <paul at planetgis.co.za
> <mailto:paul at planetgis.co.za>> wrote:
>
> How do you make a (for in) enumerator with a record? I don't use
> them for exactly this reason, and they did seem to be another
> useful language feature that turned out to be poorly implemented
> by Embarcadero. (Haven't checked with FPC).
>
>
> Here's an example (for FPC) that demonstrates it by implementing the
> "take-while" pattern:
>
> program TakeWhileExample;
>
> {$mode Delphi}{$H+}{$J-}
> {$modeswitch NestedProcVars}
> {$ImplicitExceptions Off}
> {$PointerMath On}
>
> type
> TSlice<T> = record
> public type
> PT = ^T;
> ArrayType = array of T;
> private
> FFirst, FLast, FCurrent: PT;
> function GetCurrent: T; inline;
> public
> function GetEnumerator: TSlice<T>; inline;
> function MoveNext: Boolean; inline;
> class function TakeWhile(const A: ArrayType; function F(const Val:
> T): Boolean): TSlice<T>; static; inline;
> property Current: T read GetCurrent;
> end;
>
> TTestFunc<T> = function(const Val: T): Boolean;
>
> function TSlice<T>.GetCurrent: T;
> begin
> Result := FCurrent^;
> end;
>
> function TSlice<T>.GetEnumerator: TSlice<T>;
> begin
> Result := Self;
> with Result do FCurrent := FFirst - 1;
> end;
>
> function TSlice<T>.MoveNext: Boolean;
> begin
> Inc(FCurrent);
> Exit((FCurrent <= FLast) and (FFirst <> FLast));
> end;
>
> function Test(const Val: SizeUInt): Boolean; inline;
> begin
> Exit((Val < 50000000));
> end;
>
> class function TSlice<T>.TakeWhile(const A: ArrayType; function
> F(const Val: T): Boolean): TSlice<T>;
> var
> I: SizeUInt;
> X: TTestFunc<T> absolute F;
> //FPC generates slightly better code for the "absolute" way, not
> sure why...
> begin
> with Result do begin
> FFirst := @A[0];
> FLast := @A[0];
> for I := 0 to High(A) do
> case X(A[I]) of
> True: Inc(FLast);
> False: Exit();
> end;
> end;
> end;
>
> var
> I, J: SizeUInt;
> Arr: TSlice<SizeUInt>.ArrayType;
>
> begin
> SetLength(Arr, 100000000);
> for I := 0 to 99999999 do Arr[I] := I;
> I := 0;
> J := 0;
> for I in TSlice<SizeUInt>.TakeWhile(Arr, Test) do J := I;
> WriteLn(J);
> end.
>
> _______________________________________________
> fpc-devel maillist - fpc-devel at lists.freepascal.org
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20190223/67aff17f/attachment.html>
More information about the fpc-devel
mailing list