Blog Options
Archive
<< March 2024 >>-
Tuesday 26
- TMS WEB Core with StellarDS.io backend: unparalleled productivity -
Thursday 21
- How to setup a virtual hosting environment in Delphi -
Tuesday 19
- Simplifying Full-Stack Development with our newest solution! -
Thursday 14
- Level Up Your Development: more development power at the Best Price -
Friday 8
- Recap: How it Works With Holger - Build a Full Stack Web App from Scratch
- Learn how to design a web site for blog posts with TMS WEB Core
Authors
- Aaron Decramer (16)
- Adrian Gallero (33)
- Andrew Simard (86)
- Bart Holvoet (26)
- Bernard (1)
- Bernard Roussely (1)
- Bradley Velghe (16)
- Bruno Fierens (399)
- Gjalt Vanhouwaert (30)
- Holger Flick (15)
- Marcos Douglas B. Santos (5)
- Masiha Zemarai (119)
- Nancy Lescouhier (32)
- Pieter Scheldeman (98)
- Roman Yankovsky (2)
- Tunde Keller (22)
- Wagner Landgraf (81)
- Wagner R. Landgraf (1)
Blog
All Blog Posts | Next Post | Previous PostTMS FixInsight and the inline directive
Bookmarks:Monday, April 24, 2017
The Delphi compiler allows functions and procedures to be tagged with the inline directive to improve performance. If the function or procedure meets certain criteria, the compiler will insert code directly, rather than generating a call. Embarcadero docwiki gives a list of conditions under which inlining does or does not occur.One of basic conditions says: within a unit, the body for an inline function should be defined before calls to the function are made.
TMS FixInsight 2017.04 introduces rule O805 Inline marked routine comes after its call in the same unit. Lets check FMX and VCL code to see if Embarcadero follows their own rules. Short answer: it doesnt.
I will give a couple of examples from Delphi 10.1 Berlin (version 24.0.22858.6822).
Vcl.Controls.pas
//at line 8529 procedure TWinControl.ReadState(Reader: TReader); begin DisableAlign; try inherited ReadState(Reader); finally EnableAlign; end; FixupTabList; if FParent <> nil then Perform(CM_PARENTCTL3DCHANGED, 0, 0); UpdateControlState; end;
Vcl.Controls.pas
//at line 9010 procedure TWinControl.AlignControl(AControl: TControl); var Rect: TRect; begin if not HandleAllocated or (csDestroying in ComponentState) then Exit; if FAlignLevel <> 0 then Include(FControlState, csAlignmentNeeded) else begin DisableAlign; try Rect := GetClientRect; AlignControls(AControl, Rect); finally Exclude(FControlState, csAlignmentNeeded); EnableAlign; end; end; end;
Vcl.Controls.pas
//at line 9030 procedure TWinControl.DisableAlign; begin Inc(FAlignLevel); end;
One more example from another unit:
Fmx.ListView.pas
//at line 2430 procedure TListViewBase.UpdateDeleteButtonLayout; var RelRect: TRectF; begin if (Adapter.Count < 1) or (FDeleteLayout = nil) or ((FDeleteButtonIndex = -1) and (FPrevDeleteButtonIndex = -1)) then Exit; if (FListingService <> nil) and (TListingTransitionFeature.DeleteButtonSlide in FListingService.GetTransitionFeatures) then begin FDeleteLayout.Width := DefaultDeleteButtonWidth * FDeleteModeTransitionAlpha; FDeleteButton.Opacity := 1; end else begin if FDeleteModeTransitionAlpha > 0 then FDeleteLayout.Width := DefaultDeleteButtonWidth else FDeleteLayout.Width := 0; FDeleteButton.Opacity := 0.5 + (FDeleteModeTransitionAlpha / 2); end; FDeleteLayout.Height := GetItemHeight(FDeleteButtonIndex); FDeleteLayout.Position.X := Width - FDeleteLayout.Width; if FDeleteButtonIndex = -1 then RelRect := GetItemRelRect(FPrevDeleteButtonIndex, LocalRect) else RelRect := GetItemRelRect(FDeleteButtonIndex, LocalRect); FDeleteLayout.Position.Y := (RelRect.Top + RelRect.Bottom - FDeleteLayout.Height) / 2; end;
Fmx.ListView.pas
//at line 2868 function TListViewBase.GetItemRelRect(const Index: Integer; const LocRect: TRectF; const SideSpace: Integer = 0): TRectF; begin Result := RectF(LocRect.Left + FSideSpace + SideSpace, LocRect.Top + FSideSpace + FHeightSums[Index] - FScrollViewPos, LocRect.Width - ((SideSpace + FSideSpace) * 2), GetItemHeight(Index)); if (FScrollBar <> nil) and (not HasTouchTracking) and FScrollBar.Visible then Result.Right := Result.Right - FScrollBar.Width; end;
It is not a critical issue, but this makes inline directive useless. There are more occurrences of this issue in Vcl.ExtActns.pas, FMX.ASE.Lexer.pas, FMX.Graphics.pas, FMX.Types.pas, FMX.Utils.pas and FMX.ZOrder.Win.pas.
This means that inlining conditions are not easy to follow, even though at first glance inline directive seems to be an easy way to slightly optimize your code. TMS FixInsight may help to make inlining more useful by avoiding such mistakes.
You can download TMS FixInsight trial and check your own code.
Nancy Lescouhier
Bookmarks:
This blog post has not received any comments yet.
All Blog Posts | Next Post | Previous Post