Re: [fpc-pascal] How to inline CompareFunc to Sort method in generic abstract class

2022-11-18 Thread Vojtěch Čihák via fpc-pascal

Hi,
 
I specialized my generic abstract class in a different unit with this type:
 
TRec = record
    A: Integer;
    B: Integer;
  end;
 
(A is for sorting, B is for testing of stability, i.e. for MergeSort, TimSort)
 
and compare function, declared with inline; directive:
 
function MyComptFunc(const ARec, BRec: TRec): Integer;
var i, aCnt: Integer;
begin
  aCnt:=CFComplex;
  for i:=0 to aCnt do
    Result:=(BRec.A-ARec.A);
  inc(CFCnt);
  //InterlockedIncrement(CFCnt);
end;              
 
The reason for this complex compare function is that it also measure number of 
comparisons and it can simulate more expensive comparisons (like sorting 
strings).
 
For a while, I added this unit to the second "uses" section (implementation) of 
the other unit, which is impractical, but I had
temporary access to the compare function. I tested again with ShellSort, 
sorting 2'000'000 values takes:
1380ms inlined
1515ms not inlined, ~9% slower
1430ms when compare func. is a parameter ~4% slower
 
I pass variables by value. But you are right, when I shave the function like 
this:
 
function MyComptFunc(const ARec, BRec: TRec): Integer;
begin
  Result:=(BRec.A-ARec.A);
end;
 
the results are:
750ms inlined
950ms not inlined, ~21% slower
835ms when compare func. is a parameter ~10% slower
 
so the gain of inlining is higher for sorting primitive types.
V.__

Od: "Flávio Etrusco via fpc-pascal" 
Komu: "FPC-Pascal users discussions" 
Datum: 18.11.2022 20:45
Předmět: Re: [fpc-pascal] How to inline CompareFunc to Sort method in generic 
abstract class




Em seg., 14 de nov. de 2022 15:26, Vojtěch Čihák via fpc-pascal > escreveu:,What do you mean by "be inlined"? The 
'inline' directive instructs the compiler (or is it the linker? ) to try copying the whole function 
inline, also avoiding the call (stack) setup; you can't do this for this for a general purpose 
method.I'm curious how you got that 6% figure, it seems rather large. Is this comparing the parameter 
vs virtual method approach or comparing a fully inline (no indirect call of any kind) sort function 
to some other option? Are you passing the variables by reference?Best regards,Flávio

--

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal 


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] How to inline CompareFunc to Sort method in generic abstract class

2022-11-18 Thread Flávio Etrusco via fpc-pascal
Em seg., 14 de nov. de 2022 15:26, Vojtěch Čihák via fpc-pascal <
fpc-pascal@lists.freepascal.org> escreveu:

> Hi,
>
> I wrote a generic abstract class - a list based on dynamic array (i.e.
> array of T;) and this class can be specialized elsewhere with any type
> (records or classes).
> Part of the class is sorting. There are more ways how to deliver *compare
> function* to sorting method. I can pass it as a parameter or I can define
> it as: function Compare(A, B: T): Integer; virtual; abstract;. But this way
> the function cannot be inlined.
>
> Question: Is there a way how to *inline* compare function to sorting
> method in this general purpose generic abstract class?
>
> Thanks.
>
> PS: The gain is 6-7%.
>

Hi,

What do you mean by "be inlined"? The 'inline' directive instructs the
compiler (or is it the linker? ) to try copying the whole function
inline, also avoiding the call (stack) setup; you can't do this for this
for a general purpose method.
I'm curious how you got that 6% figure, it seems rather large. Is this
comparing the parameter vs virtual method approach or comparing a fully
inline (no indirect call of any kind) sort function to some other option?
Are you passing the variables by reference?

Best regards,
Flávio
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal