Jump to content
ŁukaszDe

Very slow access to class parameters by properties

Recommended Posts

Hi,

 

I always add properties for private parameters in class with Get and Set methods:

  TSomething = class
    private
      pX: Integer;
      pY: Integer;
      function GetX: Integer;
      procedure SetX(AValue: Integer);
      function GetY: Integer;
      procedure SetY(AValue: Integer);
    public
      property X: Integer read GetX write SetX;
      property Y: Integer read GetY write SetY;      
  end;
  
function TSomething.GetX: Integer;
begin
  Result := Self.pX;
end;

procedure TSomething.SetX(AValue: Integer);
begin
  Self.pX := AValue;
end;

function TSomething.GetY: Integer;
begin
  Result := Self.pY;
end;

procedure TSomething.SetY(AValue: Integer);
begin
  Self.pY := AValue;
end;

But I found a problem with this in Delphi.

I attach an example application.

 

Access to class parameter by property with Get is almost 6 times longer than directly access.

Why?

 

If you do this in loop for 50000000 objects, than the loop is very sloow...

 

image.png.b4108081c895631c25ca7f7efa77d7b2.png

 

AccessToClassParameters.zip

Edited by ŁukaszDe

Share this post


Link to post

Add inline directive to the property accessors and check if it helps. In your example adding this directive completely eliminates function calls in the generated code.

      function GetX: Integer; inline;
      procedure SetX(AValue: Integer); inline;
      function GetY: Integer; inline;
      procedure SetY(AValue: Integer); inline;

Share this post


Link to post

Yes, this is the solution.

So If I want to use class properties in loops, I need add 'inline' to Get and Set methods?

Share this post


Link to post
15 minutes ago, ŁukaszDe said:

Yes, this is the solution.

So If I want to use class properties in loops, I need add 'inline' to Get and Set methods?

Inline is a way to hint the compiler to avoid calling a method and instead take the contents of that method and place it at the call site.

Share this post


Link to post

First, this sounds like premature optimization. Yes it is 6 times slower, but you are talking about milliseconds for huge number of objects. 

Next, if you really need to optimize for speed, you can completely remove getter and setter methods. That is the beauty of Delphi - it does not need them at all and you can freely add getter and setter methods later on (if needed) without breaking the public API.

Inline approach can solve the immediate problem, but keep in mind that inline directive is just recommendation for the compiler and under some circumstances such methods will not get inlined (though compiler will give you hint in those cases). 

Essentially you are writing a whole a lot of code for nothing.

 

  • Like 2

Share this post


Link to post

Measure again with optimization on and stackframe off (release config) - I guess the overhead for the getter/setter calls will shrink.

Share this post


Link to post

Kinda pointless to measure a getter that just returns or sets the field. Try measuring one that does some work. 

  • Like 1

Share this post


Link to post

As David says - if the setter and getter don't do anything but assignments, you can eliminate them.

 

      property X: Integer read pX write pX;
      property Y: Integer read pY write pY;    

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×