Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2014-12

about commit r29324

6 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Mattias Gaertner

Hi,

forwarded from Zeljko:

It's about fpc issue
http://bugs.freepascal.org/view.php?id=26370

It seems that TVariantArrayIterator.AtEnd loops for all Dims for no reason, so have impact on performance.

*current implementation*
function TVariantArrayIterator.AtEnd: Boolean;
var
   i : sizeint;
begin
   result:=false;
   for i:=0 to Pred(Dims) do
     if Coords^[i] >= Bounds^[i].LowBound + Bounds^[i].ElementCount then
       result:=true;
end;
*optimized implementation*
function TVariantArrayIterator.AtEnd: Boolean;
var
   i : sizeint;
begin
   result:=false;
   for i:=0 to Pred(Dims) do
     if Coords^[i] >= Bounds^[i].LowBound + Bounds^[i].ElementCount then
     begin
       result:=true;
       break;
     end;
end;

Thanks.

Mattias

Reply by email

Michael Van Canneyt
to Mattias Gaertner
Mattias Gaertner wrote 34 lines
Hi, forwarded from Zeljko: It's about fpc issue http://bugs.freepascal.org/view.php?id=26370 It seems that TVariantArrayIterator.AtEnd loops for all Dims for no reason, so have impact on performance. *current implementation* function TVariantArrayIterator.AtEnd: Boolean; var i : sizeint; begin result:=false; for i:=0 to Pred(Dims) do if Coords^[i] >= Bounds^[i].LowBound + Bounds^[i].ElementCount then result:=true; end; *optimized implementation* function TVariantArrayIterator.AtEnd: Boolean; var i : sizeint; begin result:=false; for i:=0 to Pred(Dims) do if Coords^[i] >= Bounds^[i].LowBound + Bounds^[i].ElementCount then begin result:=true; break; end; end;

Or, better yet

var
   i : sizeint;
begin
   Result:=false;
   I:=0;
   While (Not Result) and (I<=Pred(Dims)) do
     begin
     Result:= Coords^[i] >= Bounds^[i].LowBound + Bounds^[i].ElementCount;
     Inc(I);
     end;
end;

People really don't seem to get booleans, and why they scorn "While" is beyond me. All these ugly "break" statements :(

You may optimize even more by calculating Max:=pred(dims) once and doing I<=Max;

Michael.

Reply by email

Sergei Gorelkin
to Michael Van Canneyt

28.12.2014 17:36, Michael Van Canneyt пишет:

Show quoted text 58 lines
On Sun, 28 Dec 2014, Mattias Gaertner wrote: > Hi, > > forwarded from Zeljko: > > It's about fpc issue > http://bugs.freepascal.org/view.php?id=26370 > > It seems that TVariantArrayIterator.AtEnd loops for all Dims for no reason, so have > impact on performance. > > *current implementation* > function TVariantArrayIterator.AtEnd: Boolean; > var > i : sizeint; > begin > result:=false; > for i:=0 to Pred(Dims) do > if Coords^[i] >= Bounds^[i].LowBound + Bounds^[i].ElementCount then > result:=true; > end; > > *optimized implementation* > function TVariantArrayIterator.AtEnd: Boolean; > var > i : sizeint; > begin > result:=false; > for i:=0 to Pred(Dims) do > if Coords^[i] >= Bounds^[i].LowBound + Bounds^[i].ElementCount then > begin > result:=true; > break; > end; > end; Or, better yet var i : sizeint; begin Result:=false; I:=0; While (Not Result) and (I<=Pred(Dims)) do begin Result:= Coords^[i] >= Bounds^[i].LowBound + Bounds^[i].ElementCount; Inc(I); end; end; People really don't seem to get booleans, and why they scorn "While" is beyond me. All these ugly "break" statements :( You may optimize even more by calculating Max:=pred(dims) once and doing I<=Max;

Actually, in this particular case performance optimizations are pretty useless:
- TVariantArrayIterator.AtEnd method is called just once to decide whether it is necessary to iterate the array. Its usage is not typical for iterators, where such methods are called in a loop.
- To return False, it has to iterate all dimensions. After that, iterating the data of variant array will take orders of magnitude more time.
- Early exit can happen only for arrays with zero-sized dimension, which is basically invalid and indicates programmer's mistake elsewhere.

Regards,
Sergei

Reply by email

Michael Van Canneyt
to Sergei Gorelkin
Sergei Gorelkin wrote 74 lines
28.12.2014 17:36, Michael Van Canneyt пишет: > > > On Sun, 28 Dec 2014, Mattias Gaertner wrote: > >> Hi, >> >> forwarded from Zeljko: >> >> It's about fpc issue >> http://bugs.freepascal.org/view.php?id=26370 >> >> It seems that TVariantArrayIterator.AtEnd loops for all Dims for no reason, so have >> impact on performance. >> >> *current implementation* >> function TVariantArrayIterator.AtEnd: Boolean; >> var >> i : sizeint; >> begin >> result:=false; >> for i:=0 to Pred(Dims) do >> if Coords^[i] >= Bounds^[i].LowBound + Bounds^[i].ElementCount then >> result:=true; >> end; >> >> *optimized implementation* >> function TVariantArrayIterator.AtEnd: Boolean; >> var >> i : sizeint; >> begin >> result:=false; >> for i:=0 to Pred(Dims) do >> if Coords^[i] >= Bounds^[i].LowBound + Bounds^[i].ElementCount then >> begin >> result:=true; >> break; >> end; >> end; > > Or, better yet > > var > i : sizeint; > begin > Result:=false; > I:=0; > While (Not Result) and (I<=Pred(Dims)) do > begin > Result:= Coords^[i] >= Bounds^[i].LowBound + Bounds^[i].ElementCount; > Inc(I); > end; > end; > > People really don't seem to get booleans, and why they scorn "While" is beyond me. All these ugly > "break" statements :( > > You may optimize even more by calculating Max:=pred(dims) once and doing I<=Max; > Actually, in this particular case performance optimizations are pretty useless: - TVariantArrayIterator.AtEnd method is called just once to decide whether it is necessary to iterate the array. Its usage is not typical for iterators, where such methods are called in a loop. - To return False, it has to iterate all dimensions. After that, iterating the data of variant array will take orders of magnitude more time. - Early exit can happen only for arrays with zero-sized dimension, which is basically invalid and indicates programmer's mistake elsewhere.

All this may of course be true for this particular case, but it's in general always better to have optimized code. So I have committed the code as I replied it (after testing that the test program still performs as expected).

Michael.

Reply by email

Michael Van Canneyt
to Mattias Gaertner
Mattias Gaertner wrote 9 lines
On Sun, 28 Dec 2014 15:36:49 +0100 (CET) Michael Van Canneyt wrote: > [...] > People really don't seem to get booleans, and why they scorn "While" is beyond me. All these ugly "break" statements :( > > You may optimize even more by calculating Max:=pred(dims) once and doing I<=Max; Isn't "for" easier to optimize for the compiler than "while".

Now you're asking too much, I do not know this. At least the for code has 2 branches more than my code :)

Michael.

Reply by email