[fpc-pascal] code optimization

Schindler Karl-Michael karl-michael.schindler at web.de
Thu Sep 23 08:10:18 CEST 2010


> Message: 6
> Date: Wed, 22 Sep 2010 16:08:37 +0200 (CEST)
> From: stefan077 at web.de
> Subject: Re: [fpc-pascal] code optimization
> To: fpc-pascal at lists.freepascal.org
> Message-ID:
> 	<1487431390.1512221.1285164517310.JavaMail.fmail at mwmweb065>
> Content-Type: text/plain; charset=UTF-8
> 
> Hi Adrian,
> 
> it is a scientific application that I have, which has about 2000 lines of code. By extracting the most time consuming routine I now have 360 lines of code. With this code I get the following runtime results:
> 
> optimized FPC pascal   *** is  58% SLOWER  ***  than optimized DELPHI 7
> unoptimized FPC pascal *** is 60% SLOWER *** than optimized DELPHI 7
> unoptimized Delphi 7  *** is 62% SLOWER *** than optimized DELPHI 7
> 
> Thus it looks like FPC pascal is doing very bad on optimizing the code. 
> I agree, that I also have seen examples where FPC pascal code is about 10% faster than Delphi code. 
> So why does FPC pascal fail on this code?
> 
> I have included the code below. I compiled it with Delphi 7 , optimization on, range checking off, stack checking off, I/O checking off.
> For FPC pascal I used the compiler options: Â -Mdelphi -O3 -OpPENTIUMM -Cfsse2 -Cr- -Co- -CO- -Ci-
> The FPC compiler version is 2.4.0, I run under Windows XP.
> 
> any suggestions?
> Stefan

My 2 cents: 
looking at the code, i would assume that you can gain by using linked lists with pointers instead of arrays and working with the index. This would reduce the number of offset calculations. However, it means quite a rewrite. So, do you really need more speed?

Even the following primitive replace, which is not yet a conversion to a linked list already saved about 10% on Mac OS X:

      while CurrentRectangle <> 0 do
      begin
        i := CurrentRectangle;
        if (UnsortedRectangle[i].Width <= MinValleyWidth) then
          inc (TotalAreaOfFittingRectangles, UnsortedRectangle[i].Area);
        CurrentRectangle := UnsortedRectangle[CurrentRectangle].NextUnusedRectangle
      end;

-----

var
  ThisUnsortedRectangle: ^TRectangle;
...
      while CurrentRectangle <> 0 do
      begin
        ThisUnsortedRectangle := @UnsortedRectangle[CurrentRectangle];
	if (ThisUnsortedRectangle^.Width <= MinValleyWidth) then
          inc (TotalAreaOfFittingRectangles, ThisUnsortedRectangle^.Area);
        CurrentRectangle := ThisUnsortedRectangle^.NextUnusedRectangle
      end;

Btw. profiling indicates that this loop takes over 30% of cpu time. Skipping the initial assignment (i := CurrentRectangle;) made up for about 5%.

All the best

Michael Schindler


More information about the fpc-pascal mailing list