Jump to content
Guest

Extremely slow Link phase

Recommended Posts

Guest

A project of mine has begun to link very slow. It takes half a minute. I suspected the disk that the VM is on, but during linking disk access is not high at all. One core is used fully during the whole phase.

The project contains a lot and uses DevExpress rather heavily. Delphi 10.2.3, Win10, VirtualBox.

Any hints on what to check / try to reduce the time of the linking phase would be appreciated!

 

TIA,

 

/D

Share this post


Link to post

You can try those options:

1)Don't compile the third party components every time. Just compile them once when you install a new version, in both release and debug mode. Put the path for the release dcus in the "Library path", the path for debug dcus in "Debug DCUs" and the path for the .pas in the "Browsing path" This way you can still fully debug the third parties (by selecting "Use debug dcus" in the compiler options) or treat them as a black box (by unselecting use debug dcus). But the more important thing is that you will compile much less lines of code every time you do a build.

2)Look out for circular dependencies between units.

3. move used units  down from the interface uses section to the implementation uses section

4. remove not needed units from the uses section

 You can also  compile the project with the command line  and output the results to a file. Then open the file with the output, and see which units take a long time to compile.  then review the uses sections (both interface and implementation)

 

Edited by Pawel Piotrowski
  • Like 1

Share this post


Link to post

Orthogonally to the suggestions from Pawel, I'd suggest also trying to analyse what the step is actually doing while it's "being slow", with ProcessMonitor.  Even the built in Windows 10 Resource Monitor, which you can get to from the Task Manager in Windows, can be fairly useful as it allows you to isolate and drill into individual processes to monitor their behaviour as well, including handles/files opened/loaded etc etc.  Understanding what it's actually doing and working out why this step is being slow might give you ideas on how to avoid it.

Edited by ByteJuggler
  • Like 1

Share this post


Link to post
Guest

Thank you! Now o have some stuff to try. Brilliant.

@ByteJuggler i', watching the process explorer while linking, there's not much else to do 🙂

Share this post


Link to post
4 minutes ago, Dany Marmur said:

Thank you! Now o have some stuff to try. Brilliant.

@ByteJuggler i', watching the process explorer while linking, there's not much else to do 🙂

Yes... See if you spot what files, keys, or otherwise handles are being accessed/read/written and whether some stand out as being sluggish, and/or whether some of those events are excessive or slower than normal. 

 

Your problem may be inherent to the compiler linking phase and so maybe somewhat unavoidable, but this hypothesis seems dubious since you state that this has begun to be slow and so was previously quick.  And generally Delphi really doesn't take long to link.  So, something must've therefore changed to cause this one would think. 

 

(Random thought: I suppose it's worth checking the underlying disk/filesystem that the VM's virtual disk is on for problems, though I imagine this is fairly obvious and you may well have done this already.  Another question, is this in the IDE or via command line compiler?  If the former, have you tried the latter?  Either direct or via MSBuild which is a easy way to compile a project without having to think about the command line compiler switches?)

Share this post


Link to post
Guest
1 hour ago, Dany Marmur said:

@ByteJuggler i', watching the process explorer while linking, there's not much else to do 🙂

I would watch process explorer on both the host and guest VM, watch for the red (CPUkernel time) in performance chart as it concern you more than the green, such behavior have great chance that the host memory is fragmented to start with and that will has decent effect on the guest.

 

One more thing : i like process explorer, but i like another tool more, you might consider trying MiTeC Task Manager DeLuxe from  http://mitec.cz/tmx.html , it does beat process explorer and tcpview in many fields specially watching hundreds of opened threads,handles and sockets without consuming CPU power.

Share this post


Link to post

iirc circular units should affect the compiling but not the linking phase but I could be wrong.

Extremely long linking phase for has been almost always a result of extensive use of generics (either through third party or your own) because the linker then has to look through all the dcus and remove identical ones (for example every unit that uses a TList<Integer> has the code for that entire class emitted into its dcu which the linker then has to read again fix up pointers and write that to the final binary which only contains one copy of TList<Integer> - but also one for TList<string>, TList<TPerson>, TList<TcxWhatever>, ....)

 

Also sometimes very innocent looking generic APIs can cause a huge clusterf... of types being emitted into the dcus if one is not careful (I should know I wrote such APIs ^^)

 

Look into the dcu output directly and tell us the size of all dcus combined - that should give a rough estimate if that is the cause or not

Edited by Stefan Glienke
  • Like 1

Share this post


Link to post
Guest
25 minutes ago, Stefan Glienke said:

Look into the dcu output directly and tell us the size of all dcus combined - that should give a rough estimate if that is the cause or not

It's 100 MB. And a *lot* of 3rd party stuff. Getting somewhere...

4 hours ago, Pawel Piotrowski said:

1)Don't compile the third party components every time. Just compile them once when you install a new version, in both release and debug mode. Put the path for the release dcus in the "Library path", the path for debug dcus in "Debug DCUs" and the path for the .pas in the "Browsing path" This way you can still fully debug the third parties (by selecting "Use debug dcus" in the compiler options) or treat them as a black box (by unselecting use debug dcus). But the more important thing is that you will compile much less lines of code every time you do a build.

But... how?? Now i feel stupid. So when i Build, third party is built because the compiler cannot find any dcu files in the Library/Debug DCU path? And since i Build the dcus will end up in the projects subdir (project settings). Guesswork, but i'll try it.

Share this post


Link to post
13 minutes ago, Dany Marmur said:

But... how?? Now i feel stupid. So when i Build, third party is built because the compiler cannot find any dcu files in the Library/Debug DCU path? And since i Build the dcus will end up in the projects subdir (project settings). Guesswork, but i'll try it. 

Before doing any changes in this direction, compare times of Rebuilding with Shift-F9 and Compiling with Ctrl-F9. The latter is almost purely link time. Probably build time is not a problem.

Share this post


Link to post
Guest
2 minutes ago, Fr0sT.Brutal said:

Probably build time is not a problem.

Huge difference. A big path of DevExpress is built for each builld. Trying to get rig of it...

Share this post


Link to post

Especially with DevExpress everything should be setup perfectly if you run their setup.

You only end up recompiling their sources (and even if that should not affect linking time it adds a bunch to the compile time) if you manually put the directories with their sources into your library or project search path.

 

Within the DevExpress installation directory there should be a Library folder (besides all the different ExpressWhatever folders for their different component suites). That Library folder contains all the dcus along with dfm and res files being produced by the compilation during their setup.

That directory is being put into the library path. If anything else is the case then that is not ideal.

 

P.S.: If you don't mind and are able to send me the map file of your application and I can quickly run that through some tool I wrote to peek if it suffers from heavy generic bloat.

Edited by Stefan Glienke
  • Like 1

Share this post


Link to post
Guest

@Stefan Glienke, so i removed the DX\Sources path from my Library path and the dcu folder size shrank to 13 MB. I have to continue with some real work to feel the difference but it does not feel like it was the "thing".

Share this post


Link to post
Guest

I have;

 

1. Seen to it that DevExpress is not compiled at each build. Even if linking is still slower than i would expect, of course building is MUCH faster. So THANKS for this. A decade ago i had to change 3rd party code so much (to help with bugs) that i have since never reflected over the fact that you can have debug dcu's and still trace along. Phew...

2. I knew i had two circular dependencies. They are now gone.

3. I usually take care and format the uses clauses. So i do not think there's so much i can do except maybe remove a lot of DX units that the IDE added. But that seems like a long shot.

 

Linking is still more than 20 seconds 😞 the IDE hides and displays the "compile dialog" three times before the application is started for debugging.

Also the IDE repaints a lot when switching to Debug Layout but i cannot see that for example the DWM works hard and it usually does when excessive repainting is the culprit.

 

I'll move on to putting up a map-file for Stefan tomorrow, if not for anything else so because it's interesting. Need to find a good place, i do not trust the sharing services with these things.

 

I'm working against a deadline and it's always a drag to spend time saving time without being able to succeed to save time. But it's the normal thing; ... this is taking long ... i should break it out in a small project ... just one more try, it could be that pesky pointer ... [repeat]

Share this post


Link to post
1 hour ago, Dany Marmur said:

Linking is still more than 20 seconds 😞 the IDE hides and displays the "compile dialog" three times before the application is started for debugging.

Also the IDE repaints a lot when switching to Debug Layout but i cannot see that for example the DWM works hard and it usually does when excessive repainting is the culprit.

I noticed that 10.2 noticably slows down due to the progress dialog. When compiling the exact same code in the commandline compiler or without the dialog.

It even has been reported (https://quality.embarcadero.com/browse/RSP-22056) - not sure exactly what has been done since then as we won't upgrade from 10.1 for other reasons so my 10.2 and 10.3 installations don't see any huge projects.

  • Thanks 2

Share this post


Link to post

You have to disable every skinning as the whole dialog will be repainted on every compiled line.

I'm also stuck on 10.1 but this seems to be the right decision for now.

  • Thanks 1

Share this post


Link to post
11 hours ago, Dany Marmur said:

Linking is still more than 20 seconds 😞 the IDE hides and displays the "compile dialog" three times before the application is started for debugging.

Also the IDE repaints a lot when switching to Debug Layout but i cannot see that for example the DWM works hard and it usually does when excessive repainting is the culprit.

is your project using visual inheritance? 

https://quality.embarcadero.com/browse/RSP-15417

 

  • Thanks 1

Share this post


Link to post
Guest
13 hours ago, Stefan Glienke said:

Whaa... argh!

13 hours ago, Attila Kovacs said:

You have to disable every skinning as the whole dialog will be repainted on every compiled line.

I have put a lot of effort into DX Skin/Ribbon tweaking for working in the IDE. I am aware. What i did not (even though i thought about it) contemplate in depth was that these things can affect compile/link time. Thats... sigh.

3 hours ago, RonaldK said:

is your project using visual inheritance? 

https://quality.embarcadero.com/browse/RSP-15417

Yes, and quite a lot. Phew...

 

Again - thank you all. This is definately to do with painting. The difference between running the VM on my workstation (Xeon, 4K screen at 100%) and in my laptop (8 gen i7, 1920*1080) is very very noticeable. What threw me in other directions is that i "discovered" the DX-Ribbon-refresh thing bu watching the WDM process. During compile-link it is not as proficient in the process explorer.

 

This is a rather big and ver NEW project. I was migrated from berlin to tokyo. I had a lot of other rearrangements that could affect compile/link time so...

 

I have to do other stuff now, but i'll let you know how it goes.

Share this post


Link to post
Guest

Background compilation, no dialog:

 

Build immediately after opening the IDE (no dfms open): 19 sec

Build in IDE after having opened one datamodule and two forms (with visual inher and DX Ribbon, of course no DX skins): 48 sec

msbuild: 19 sec

 

OK.

Share this post


Link to post
Guest

After doing an external build, the IDE still "Links" using 27 seconds when i hit "Run"... would that work better if i sucessfully compile from the IDE using the "Use Msbuild externally..." checkbox?

Perhaps i should revert to Berlin? But that feel like a rather huge effort.

Share this post


Link to post
Guest

It also takes a lot of time to exit the application that is being debugged. This is all about repainting re DX Ribbon + visual inheritance.

If i get the time i'll try putting up the project in Berlin. Thanks to all for you help!!

Share this post


Link to post
24 minutes ago, Dany Marmur said:

It also takes a lot of time to exit the application that is being debugged. This is all about repainting re DX Ribbon + visual inheritance.

If i get the time i'll try putting up the project in Berlin. Thanks to all for you help!!

The problem started with Berlin, you have to go to earlier versions and deactivate/delete the Live Bindings DLLs.

My workaround was a redesign of the visual inheritans with the DX ribbon. 

 

Not only the debugging is slow. Try to navigate to a variable declared in a unit, which inherits from a DX Ribbon Form. That's real fun 😉 I can take minutes.

Edited by RonaldK

Share this post


Link to post
Guest
3 minutes ago, RonaldK said:

deactivate/delete the Live Bindings DLLs

Always 🙂

4 minutes ago, RonaldK said:

My workaround was a redesign of the visual inheritans with the DX ribbon. 

Could you elaborate re the ribbon, thanks!

Share this post


Link to post
3 minutes ago, Dany Marmur said:

Could you elaborate re the ribbon, thanks!

Instead of having many TForm inheritance with different DXRibbons, I've now one master TForm with a full feature Ribbon (all possible Buttons). 

I'm using a Pagecontrol on this Ribbon-Form to embeded the other TForms.

The mainform "ask" the active embeded Form for button enabled/visible/Click.

 

There is no visual inheritance of DX Ribbon forms anymore.

Share this post


Link to post
Guest

@RonaldK, i see. Sigh. I'm really not sure if that approach is good for this project. I have contemplated similar stuff. Should revisit that perhaps.

 

Share this post


Link to post
On 10/23/2019 at 2:45 PM, Dany Marmur said:

@RonaldK, i see. Sigh. I'm really not sure if that approach is good for this project. I have contemplated similar stuff. Should revisit that perhaps.

 

Or to return to a Delphi version < Berlin.

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

×