Recent

Author Topic: Free Pascal - The Swift Flavour  (Read 1570 times)

lagprogramming

  • Full Member
  • ***
  • Posts: 162
Free Pascal - The Swift Flavour
« on: March 19, 2021, 06:54:01 pm »
The Swift Flavour of Free Pascal might increase the responsiveness of some Free Pascal built applications. The homepage is at www.lag.coolpage.biz/index_it_fcs_swift.html

In order to apply(install) the Swift flavour for Free Pascal, the following steps are recommended:

1) Check that you have a sane working environment by recompiling Free Pascal clean.

2) Download the archive containing the flavouring file from www.lag.coolpage.biz/downloads/fcs_fpc_swift.7z and the archive containing the F.C.S. console clients from www.lag.coolpage.biz/downloads/fcsconsole.7z. Extract the content of the two archives in a temporary directory.

3) Apply(Install) the flavour by executing:
Code: Pascal  [Select][+][-]
  1. fcsconsole fpc_swift.fcs APPLY 'MACRO{MACRO_FPC_DIRECTORY}=fpc_directory'
where "fpc_directory", directory that contains source files, looks like "c:\freepascal\" or "/home/user/fpc/"
"./fcsconsole_linux_x86_64 fpc_swift.fcs APPLY 'MACRO{MACRO_FPC_DIRECTORY}=/home/user/fpc/" is an example for a linux user.

4) Rebuild Free Pascal to make sure everything appears to be fine.

5) Rebuild all your programs using the flavoured Free Pascal.


Notes:

If things appear to be slower make sure you've not rebuilt using a lower optimizations level. For example, your original executable file was built with level 3 optimizations, you modify the source files through flavouring and you rebuild with level 1 optimizations.

The flavour can be removed(uninstalled) by executing: fcsconsole fpc_swift.fcs REVERSE 'MACRO{MACRO_FPC_DIRECTORY}=fpc_directory'

The quotes(') of the MACRO parameter are useful when the fpc_directory contains spaces.

Additional information can be obtained by executing:
Code: Pascal  [Select][+][-]
  1. fcsconsole fpc_swift.fcs showuserinfo



Years ago I've started looking at Free Pascal's source code. During this time I've modified a couple of routines. Most of the modifications are local optimizations with no measurable speed increase on my computer. I maintain this flavour because it's involved in the development of other projects.

avk

  • Sr. Member
  • ****
  • Posts: 411
    • my self-education project
Re: Free Pascal - The Swift Flavour
« Reply #1 on: March 19, 2021, 07:23:30 pm »
Something is not very clear, AFAIK Swift is one of the slowest compiled languages, so what are you talking about?

MarkMLl

  • Hero Member
  • *****
  • Posts: 2561
Re: Free Pascal - The Swift Flavour
« Reply #2 on: March 19, 2021, 09:46:15 pm »
I don't have a good feeling about this: a very occasional member of the community inviting people to install an opaque patch with no adequate explanation of what it does.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

lagprogramming

  • Full Member
  • ***
  • Posts: 162
Re: Free Pascal - The Swift Flavour
« Reply #3 on: March 26, 2021, 01:51:14 pm »
   As far as I know, according to the license of Free Pascal, it's mandatory to release such modifications to the public. A good place to announce such modifications is the forum found at Free Pascal's homepage - Third Party Announcements. There is no reason why the community should not be able to have access to these modifications.
   
   Most of the modifications are minor optimizations.
   
   Some comparisons with -1 have been replaced with comparisons with zero. For example function TFPList.Remove has been modified from
Code: Pascal  [Select][+][-]
  1. function TFPList.Remove(Item: Pointer): Integer;
  2. begin
  3.   Result := IndexOf(Item);
  4.   If Result <> -1 then
  5.     Self.Delete(Result);
  6. end;
to
Code: Pascal  [Select][+][-]
  1. function TFPList.Remove(Item:Pointer):Integer;
  2. begin
  3. Result:=IndexOf(Item);
  4. If Result>=0 then Self.Delete(Result);
  5. end;

   Some useless conditions have been removed. For example "if Result=Count then Result:=-1;" has been removed from Function TStrings.IndexOf
Code: Pascal  [Select][+][-]
  1. Function TStrings.IndexOf(const S: string): Integer;
  2. begin
  3.   Result:=0;
  4.   While (Result<Count) and (DoCompareText(Strings[Result],S)<>0) do Result:=Result+1;
  5.   if Result=Count then Result:=-1;
  6. end;
has been changed to
Code: Pascal  [Select][+][-]
  1. Function TStrings.IndexOf(const S:string):Integer;
  2. begin
  3. Result:=-1;
  4.    repeat
  5.    inc(result);
  6.    if Result>=Count then break;
  7.    if DoCompareText(Strings[Result],S)=0 then exit;
  8.    until false;
  9. Result:=-1;
  10. end;

   Some variables have been removed and series of "if" conditions have been improved. For example Function FileGetAttr has been modified from
Code: Pascal  [Select][+][-]
  1. Function FileGetAttr (Const FileName : RawByteString) : Longint;
  2. Var
  3.   SystemFileName: RawByteString;
  4.   Info : Stat;
  5.   res : Integer;
  6. begin
  7.   SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
  8.   res:=FpLStat(pointer(SystemFileName),Info);
  9.   if res<0 then
  10.     res:=FpStat(pointer(SystemFileName),Info);
  11.   if res<0 then
  12.     Result:=-1
  13.   Else
  14.     Result:=LinuxToWinAttr(SystemFileName,Info);
  15. end;
to
Code: Pascal  [Select][+][-]
  1. Function FileGetAttr(const FileName:RawByteString):Longint;
  2. var SystemFileName:RawByteString;
  3.     Info:Stat;
  4. begin
  5. SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
  6. if FpLStat(pointer(SystemFileName),Info)<0 then
  7.    begin
  8.    if FpStat(pointer(SystemFileName),Info)<0 then exit(-1);
  9.    end;
  10. Result:=LinuxToWinAttr(SystemFileName,Info);
  11. end;

   Some assignments to function results have been improved. For example Function IsDelimiter has been modified from
Code: Pascal  [Select][+][-]
  1. Function IsDelimiter(const Delimiters, S: string; Index: SizeInt): Boolean;
  2.  
  3. begin
  4.   Result:=False;
  5.   If (Index>0) and (Index<=Length(S)) then
  6.     Result:=Pos(S[Index],Delimiters)<>0; // Note we don't do MBCS yet
  7. end;
to
Code: Pascal  [Select][+][-]
  1. Function IsDelimiter(const Delimiters,S:string; Index:SizeInt):Boolean;
  2. begin
  3. Result:=((Index>0)and(Index<=Length(S)))and(Pos(S[Index],Delimiters)<>0);// Note we don't do MBCS yet
  4. end;

   There are also routines with significant content change. For example function TFPReaderBMP.CountBits has been modified from
Code: Pascal  [Select][+][-]
  1. function TFPReaderBMP.CountBits(Value : byte) : shortint;
  2. var i,bits : shortint;
  3. begin
  4.   bits:=0;
  5.   for i:=0 to 7 do
  6.   begin
  7.     if (value mod 2)<>0 then inc(bits);
  8.     value:=value shr 1;
  9.   end;
  10.   Result:=bits;
  11. end;
to
Code: Pascal  [Select][+][-]
  1. function TFPReaderBMP.CountBits(Value:byte):shortint;
  2. begin
  3. result:=popcnt(Value);
  4. end;

   As I've written in the first post, on my system I didn't witnessed a speed increase revolution. However, this doesn't mean that building particular applications, on particular architectures, can't benefit from such modifications.

Handoko

  • Hero Member
  • *****
  • Posts: 4230
  • My goal: build my own game engine using Lazarus
Re: Free Pascal - The Swift Flavour
« Reply #4 on: March 26, 2021, 02:44:21 pm »
Thank you lagprogramming for the explanation. I think because you did not explain in detail on the first post so some may misunderstand your modifications has something to do with Swift Programming Language.

And thank you for sharing back the improvements you have done for Free Pascal.

PascalDragon

  • Hero Member
  • *****
  • Posts: 2988
  • Compiler Developer
Re: Free Pascal - The Swift Flavour
« Reply #5 on: March 26, 2021, 03:10:08 pm »
   Most of the modifications are minor optimizations.
   
   Some comparisons with -1 have been replaced with comparisons with zero. For example function TFPList.Remove has been modified from

In my opinion it would be better to provide bug reports with a patch for each of these, then everyone can benefit.

Trenatos

  • Hero Member
  • *****
  • Posts: 534
    • MarcusFernstrom.com
Re: Free Pascal - The Swift Flavour
« Reply #6 on: March 26, 2021, 07:32:37 pm »
Sounds like these would be good improvements to add as patches at http://bugs.freepascal.org/ for inclusion in FPC if accepted

MarkMLl

  • Hero Member
  • *****
  • Posts: 2561
Re: Free Pascal - The Swift Flavour
« Reply #7 on: March 26, 2021, 09:55:57 pm »
Sounds like these would be good improvements to add as patches at http://bugs.freepascal.org/ for inclusion in FPC if accepted

Seconded. My apologies for my harsh words earlier, before OP explained what he'd got.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

440bx

  • Hero Member
  • *****
  • Posts: 2310
Re: Free Pascal - The Swift Flavour
« Reply #8 on: March 27, 2021, 02:28:30 am »
Some assignments to function results have been improved. For example Function IsDelimiter has been modified from
Code: Pascal  [Select][+][-]
  1. Function IsDelimiter(const Delimiters, S: string; Index: SizeInt): Boolean;
  2.  
  3. begin
  4.   Result:=False;
  5.   If (Index>0) and (Index<=Length(S)) then
  6.     Result:=Pos(S[Index],Delimiters)<>0; // Note we don't do MBCS yet
  7. end;
to
Code: Pascal  [Select][+][-]
  1. Function IsDelimiter(const Delimiters,S:string; Index:SizeInt):Boolean;
  2. begin
  3. Result:=((Index>0)and(Index<=Length(S)))and(Pos(S[Index],Delimiters)<>0);// Note we don't do MBCS yet
  4. end;
The following is just a nitpick but, I believe that when repeated many times, as is usually the case in a large program, it does make a difference.  Specifically, both of the versions above don't make it crystal clear what the function preconditions are for it to operate properly.  I would personally prefer something along the lines of
Code: Pascal  [Select][+][-]
  1. Function IsDelimiter(const Delimiters, S: string; Index: SizeInt): Boolean;
  2. begin
  3.   result := false;   { always initialize the result upon entry }
  4.  
  5.   { preconditions }
  6.   if (Index <= 0) or (Index > Length(S)) then exit;  { preconditions violated }
  7.  
  8.   { preconditions met }
  9.  
  10.   Result := Pos(S[Index], Delimiters) <> 0; // Note we don't do MBCS yet
  11. end;
It's a very small thing but, the separation of preconditions from the operations required to accomplish the function's purpose makes the code easier to understand and, maintain in the long run (particularly for more complex functions/procedures.)

I can't help it, I have to say something about it, I find the common tendency in programmers to produce hard to read "blobs of text" rather regrettable (quite likely another negative side effect from programming in C.)  Some whitespace helps create groups of instructions that are logically related and, it really makes reading the code a lot easier.  Whitespace is cheaper than beer and, it does not negatively affect the "user's" visual abilities (among others.)

just $0.02

FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

lagprogramming

  • Full Member
  • ***
  • Posts: 162
Re: Free Pascal - The Swift Flavour
« Reply #9 on: April 26, 2021, 02:08:06 pm »
    Some functions and procedures that have been modified have a faster execution speed. As expected, there are downsides to this increase of execution speed: the modified code is often hard to be understood(read), hard to debug, which means very hard to maintain if it would be pushed in the official tree. So, most of these routines don't belong in an official release, at least in my point of view.
    As far as I've seen during the years, the routines with minor improvements are not welcome in the official tree because the efforts required by the developers to read and push the patches are considered greater than the eventual gains. If the situation has changed in the meantime, I would consider proposing patches using Mantis. I'd start with minor things like code cleanups. For example rtl/objpas/sysutils/sysstr.inc has a function CompareStr(const S1, S2: string): Integer; where variable "res" is declared but never used.
    Mostly because of the disadvantages presented above, I think that many of these modifications should not be in the official release, so I've released them as a flavour for Free Pascal. You can modify any existing Free Pascal source code, no matter the svn branch(fixes, trunc...), revision number, version, no matter if it's vanilla, a fork or whatever else. You don't depend on mammoths like sourceforge, github, additional license agreements, not even internet. Look at it like the last "patch"-like modifications to your local FP source code files.
   I'm glad that this forum announcement lead to an improvement, bug  #0038728(Optimization of TFPReaderBMP.CountBits) already fixed and bug #0038729 (Implement PopCnt for ARM NEON extension).

 

TinyPortal © 2005-2018