Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2011-07

Once again about the size of the executable

9 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Max Vlasov

Hi,

I decided to take a quick look at the lazarus executable size. Sure that was discussed several times, I just wanted to do quick tests with several units that are far from forms or related to understand how they affect the size of executable.

So apparently there's the controls unit that triggers the largest part. If you add this to the uses list of a simple program you will get well-known "minimum" size program. There's nothing one can do currently with this since it's triggers many important things in initialization section, uses Forms for Delphi compatibility (that also triggers much) so no chances to find anything real to remove. But to my surprise the unit Graphics also triggered the same size 1.5MB on windows.

So after some investigation I came up with a one minor fix. If ImgList is removed from the Themes implementation section and DrawIcon(ACanvas...) made blank, Graphics no longer indirectly uses Controls unit . The only place that uses this overloaded DrawIcon(ACanvas method is \lcl\include\headercontrol.inc. Sure this change is not a fix that works, but just proof-of-concept change that shows that this method either can be moved somewhere or replace with something else allowing existence of Graphics without Widget Set (Factory) usage.

So, I wanted to suggest some fixing at least to allow for example command-line programs that only use Graphics for conversion or related to be 800-900 kb smaller. I was impressed by the fact that so many units (see the listing, until InterfaceBase) don't directly or indirectly uses any WidgetSet-related units so it looked like the developers take these things into account.

On the other side ff it's fixed there's no guarantee that lcl that is constantly in a development state won't get some new functionality returning "uses Controls" on some level.

Below is the program that I used for my inquiry. It contains no real form so just shows how much is added just by adding a unit to the uses list. You can see the sizes for the corresponding step in the comments (if there's no commend, adding this unit either didn't add to the size or added not much).

Other then this moment I described, it's interesting that different image formats self-registering adds about 200k to the size of the executable. I know it's almost nothing comparing to the current "minimum" size, but it's also something to think about (maybe introduce some define like OMIT_IMAGE_FORMATS_REGISTER that will allow decreasing the size)

So just my thoughts maybe to continue the discussion or bury it :)

Max

------------------------------

program sizeenquiry;
{$mode objfpc}{$H+}

uses
? {30k, the size with empty uses list }
{$R *.res} { 160k }
? Classes, { 295k }
? SysUtils,
? Math, Types, Contnrs, FPCAdds, LCLversion,
? FileUtil,
? FPImage, FPCanvas, { 307k }
? FPWriteBMP,
? FPWritePNG, PNGComn,
? FPReadPNM, FPWritePNM,
? FPReadJpeg, FPWriteJpeg,
? FPReadTiff, FPTiffCmn, { 485k }
? FPReadGif,
? AvgLvlTree,
? LCLStrConsts, LCLType, LCLProc, { 493k }
? LMessages,
? LResources, { 510k }
? LCLResCache,
? GraphType, IcnsTypes, GraphMath, WSReferences,
? SyncObjs,
? FPReadPNG,? {538k}
? FPWriteTiff,
? BMPComn,
? LCLClasses,
? WSLCLClasses,
? UTF8Process, Maps, TmSchema,
?? { if we keep the things as it is now, adding
???? Themes or IntfGraphics or Graphics or LCLInfo or InterfaceBase ???? below makes exe 1.5MB immediately
???? Bur if we remove ImgList from Themes' implementation uses section and also make method DrawIcon(ACanvas: TPersistent;..blank ???? to fit this removing, then the following kilobytes numbers are valid ???? }
? InterfaceBase, { 640k } {uses Themes that uses ImgList that uses WSImgList that triggers WS-Binding }
? IntfGraphics,
? Themes,
? LCLIntf,
? Graphics {the size of exe on this step with non-patched Themes ~ 1.5MB, with patched ~ 640k}
? ;
begin
end.

Reply by email

Alexander Klenin
to Max Vlasov
Max Vlasov wrote 18 lines
So apparently there's the controls unit that triggers the largest part. If you add this to the uses list of a simple program you will get well-known "minimum" size program. There's nothing one can do currently with this since it's triggers many important things in initialization section, uses Forms for Delphi compatibility (that also triggers much) so no chances to find anything real to remove. But to my surprise the unit Graphics also triggered the same size 1.5MB on windows. So after some investigation I came up with a one minor fix. If ImgList is removed from the Themes implementation section and DrawIcon(ACanvas...) made blank, Graphics no longer indirectly uses Controls unit . The only place that uses this overloaded DrawIcon(ACanvas method is \lcl\include\headercontrol.inc. Sure this change is not a fix that works, but just proof-of-concept change that shows that this method either can be moved somewhere or replace with something else allowing existence of Graphics without Widget Set (Factory) usage.

This is excellent news for me, since I have long planned to get rid of Graphics unit in TAChart to avoid widgetset dependency. I thought that Graphics depends on WidgetSet due to Delphi compatibility. If in fact the dependency is just an implementation accident, I would like it very much to see it gone.

Can you post a patch of your changes for easier review/discussion?

Alexander S. Klenin

Reply by email

Max Vlasov
to Alexander Klenin
Alexander Klenin wrote 19 lines
On Fri, Jul 8, 2011 at 08:30, Max Vlasov wrote: > So after some investigation I came up with a one minor fix. If ImgList > is removed from the Themes implementation section and > DrawIcon(ACanvas...) made blank, Graphics no longer indirectly uses > Controls unit . The only place that uses this overloaded > DrawIcon(ACanvas method is \lcl\include\headercontrol.inc. Sure this > change is not a fix that works, but just proof-of-concept change that > shows that this method either can be moved somewhere or replace with > something else allowing existence of Graphics without Widget Set > (Factory) usage. This is excellent news for me, since I have long planned to get rid of Graphics unit in TAChart to avoid widgetset dependency. I thought that Graphics depends on WidgetSet due to Delphi compatibility. If in fact the dependency is just an implementation accident, I would like it very much to see it gone. Can you post a patch of your changes for easier review/discussion?

Sorry for my free form of the patch, it looks like the following changes in Themes.pas

implementation
uses
  SysUtils, InterfaceBase, LCLIntf, GraphType, Graphics, ImgList;
implementation
uses
  SysUtils, InterfaceBase, LCLIntf, GraphType, Graphics{, ImgList};

and

procedure TThemeServices.DrawIcon(ACanvas: TPersistent;
  Details: TThemedElementDetails; const P: TPoint; AImageList:
TPersistent;  Index: Integer);
begin
...
end;

to

procedure TThemeServices.DrawIcon(ACanvas: TPersistent;
  Details: TThemedElementDetails; const P: TPoint; AImageList:
TPersistent;  Index: Integer);
begin
end;

so just make this overloaded DrawIcon do nothing.

Max

Reply by email

Mattias Gaertner
to Max Vlasov
Show quoted text 51 lines
On Sat, Jul 9, 2011 at 12:26 AM, Alexander Klenin wrote: > On Fri, Jul 8, 2011 at 08:30, Max Vlasov wrote: >> So after some investigation I came up with a one minor fix. If ImgList >> is removed from the Themes implementation section and >> DrawIcon(ACanvas...) made blank, Graphics no longer indirectly uses >> Controls unit . The only place that uses this overloaded >> DrawIcon(ACanvas method is \lcl\include\headercontrol.inc. Sure this >> change is not a fix that works, but just proof-of-concept change that >> shows that this method either can be moved somewhere or replace with >> something else allowing existence of Graphics without Widget Set >> (Factory) usage. > > This is excellent news for me, since I have long planned to get rid of > Graphics unit in TAChart to avoid widgetset dependency. > I thought that Graphics depends on WidgetSet due to Delphi compatibility. > If in fact the dependency is just an implementation accident, > I would like it very much to see it gone. > > Can you post a patch of your changes for easier review/discussion? > Sorry for my free form of the patch, it looks like the following changes in Themes.pas implementation uses SysUtils, InterfaceBase, LCLIntf, GraphType, Graphics, ImgList; implementation uses SysUtils, InterfaceBase, LCLIntf, GraphType, Graphics{, ImgList}; and procedure TThemeServices.DrawIcon(ACanvas: TPersistent; Details: TThemedElementDetails; const P: TPoint; AImageList: TPersistent; Index: Integer); begin ... end; to procedure TThemeServices.DrawIcon(ACanvas: TPersistent; Details: TThemedElementDetails; const P: TPoint; AImageList: TPersistent; Index: Integer); begin end; so just make this overloaded DrawIcon do nothing.

I restructured a few things so Graphics no longer depends on Controls.

Mattias

Reply by email

Alexander Klenin
to Max Vlasov
Max Vlasov wrote 8 lines
On Sun, Jul 10, 2011 at 3:15 AM, Mattias Gaertner wrote: > > I restructured a few things so Graphics no longer depends on Controls. > Confirmed, uses graphics -> 640k on Windows Mattias, nice solution with the event :)

Thanks from me too.
No for the more tricky question -- should Controls unit depend in WidgetSet?
On the one hand, the name suggests that it should ;-) On the other, it in in LCLBase package, whish is supposed to be widgetset-independent, no?

Alexander S. Klenin

Reply by email

Mattias Gaertner
to Alexander Klenin
Show quoted text 16 lines
On Sun, Jul 10, 2011 at 18:56, Max Vlasov wrote: > On Sun, Jul 10, 2011 at 3:15 AM, Mattias Gaertner > wrote: >> >> I restructured a few things so Graphics no longer depends on Controls. >> > > Confirmed, uses graphics -> 640k on Windows > Mattias, nice solution with the event :) Thanks from me too. No for the more tricky question -- should Controls unit depend in WidgetSet? On the one hand, the name suggests that it should ;-) On the other, it in in LCLBase package, whish is supposed to be widgetset-independent, no?

It depends on the abstract widgetset, not the real widgetset.

Mattias

Reply by email

Alexander Klenin
to Mattias Gaertner
Mattias Gaertner wrote 7 lines
> No for the more tricky question -- should Controls unit > depend in WidgetSet? > On the one hand, the name suggests that it should ;-) > On the other, it in in LCLBase package, whish is supposed to be > widgetset-independent, no? It depends on the abstract widgetset, not the real widgetset.

I guess that is true for much of LCL.
I mean, if the project uses only Controls unit, can it be compiled/used without any real widgetset, even nogui one?

Alexander S. Klenin

Reply by email

Mattias Gaertner
to Alexander Klenin
Show quoted text 13 lines
On Sun, Jul 10, 2011 at 19:34, Mattias Gaertner wrote: >> No for the more tricky question -- should Controls unit >> depend in WidgetSet? >> On the one hand, the name suggests that it should ;-) >> On the other, it in in LCLBase package, whish is supposed to be >> widgetset-independent, no? > > It depends on the abstract widgetset, not the real widgetset. I guess that is true for much of LCL. I mean, if the project uses only Controls unit, can it be compiled/used without any real widgetset, even nogui one?

No.

Well, maybe if you use only some enums and WPO.

Mattias

Reply by email