Skip to content
GitLab
  • Menu
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
    • Switch to GitLab Next
  • Sign in / Register
  • FPC Source FPC Source
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 1,278
    • Issues 1,278
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 59
    • Merge requests 59
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Packages & Registries
    • Packages & Registries
    • Package Registry
    • Container Registry
    • Infrastructure Registry
  • External wiki
    • External wiki
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • FPC
  • FPCFPC
  • FPC SourceFPC Source
  • Issues
  • #39725
Closed
Open
Issue created May 17, 2022 by Okoba@OkobaPatino

Optimizing the counter code

Summary

I have a simple code checking for a value. In the first test, it does everything in one go, but I want to update the counter an skip some values and report status. If I do the update of "I" in the function, everything is fine, but If I call a function to check even if inline, because of "var" parameter, FPC does not optimize the code. I like to know if this is a proper response of FPC or it is an optimization missed.

This is a very simplified case of the problem, in the real work, I need to change Value of I depending the results. So I can not do it in the main function, and need to call another function for code maintainability.

System Information

Lazarus 2.3.0 (rev main-2_3-1804-g43e385a90b) FPC 3.3.1 x86_64-win64-win32/win64

Example Project

program project1;
 
uses
  Classes,
  SysUtils;
 
  function Test1(const Value: array of Integer): Int64;
  var
    I: Integer;
  begin
    Result := 0;
 
    I := 0;
    repeat
      repeat
        if Odd(Value[I]) then
          Result += 1;
        I += 1;
      until I = Length(Value);
    until True;
  end;
 
  function Check(var I: Integer): Boolean; inline;
  begin
    Result := True;
  end;
 
  function Test2(const Value: array of Integer): Int64;
  var
    I: Integer;
  begin
    Result := 0;
 
    I := 0;
    repeat
      repeat
        if Odd(Value[I]) then
          Result += 1;
        I += 1;
      until I = Length(Value);
    until Check(I);
  end;
 
  function Test3(const Value: array of Integer): Int64;
  var
    I, TempI: Integer;
  begin
    Result := 0;
 
    I := 0;
    repeat
      TempI := I;
      repeat
        if Odd(Value[TempI]) then
          Result += 1;
        TempI += 1;
      until TempI = Length(Value);
      I := TempI;
    until Check(I);
  end;
 
var
  Value: array of Integer;
  Tick: QWord;
begin
  SetLength(Value, 1000000000);
 
  Tick := GetTickCount64;
  Test1(Value);
  WriteLn(GetTickCount64 - Tick);
 
  Tick := GetTickCount64;
  Test2(Value);
  WriteLn(GetTickCount64 - Tick);
 
  Tick := GetTickCount64;
  Test3(Value);
  WriteLn(GetTickCount64 - Tick);
 
  ReadLn;
end.
 

What is the current bug behavior?

In this test, Test2 is two times slower as FPC does not use register for I. In Test3, I made a Temp variant to tricked FPC to use register.

More information

https://forum.lazarus.freepascal.org/index.php?topic=59340.0

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking