The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,406 other followers

Delphi: Optimizing extremely long compile times

Posted by jpluimers on 2010/08/26

Anthony Frazier mentions two very true paths for optimizing your Delphi compile times:

  1. Avoid units with the “read-only” attribute set.
  2. Avoid large circular dependency groups, particularly if you put everything in the interface’s uses clause rather than the implementation uses clause.

To get rid of the second, you should split your interface and your implementation.
Often, one of these two solutions work for that well:

  • Create the interface as a base class, then implement it in a descendant.
  • Create the interface as a Delphi interface, then implement it in a class.

Only if those options do not work, then start using Delphi SpeedUp by Andreas Hausladen.

–jeroen

Via: TPersistent.com » Blog Archive » The Power of Open Source.

19 Responses to “Delphi: Optimizing extremely long compile times”

  1. Xepol said

    “Avoid large circular dependency groups, particularly if you put everything in the interface’s uses clause rather than the implementation uses clause”

    You can’t create circular dependancies without using the implementation uses clause. Circular dependacies at the interface level will not compile under any conditions.

    • Yeah, I suppose a “does not compile at all” situation could be considered INFINITE compilation time, so removing circular unit references reduces INFINITE to FINITE, which is undeniably an impressive optimization. LOL

    • jpluimers said

      Actually, I was talking about ‘groups’.
      Having unit A using unit B and unit C in the interface, where B and C are in cycles can in fact make compiler performance worse than having B and C used in the implementation of A.

      Does that make my point more clear?
      –jeroen

  2. Pete R. said

    You said:

    * Create the interface as a base class, then implement it in a descendant.
    * Create the interface as a Delphi interface, then implement it in a class.

    This does not make sense. “Create the [unit] interface as a base class.” The unit interface can only be created as the unit interface. Units may contain classes (or they may not). Units are not classes. This is like saying “create the egg as an egg carton.”

    “[T]hen implement it in a descendant.” Except for abstract methods, a base class must be implemented. You can’t skip implementing it simply by creating descendant classes.

    “Create the [unit] interface as a Delphi interface.” Same problem. See above.

    “[T]hen implement it in a class.” If by “it” you mean interfaces descended from IUnknown then of course you would implement it in a class. There is no other way to implement an interface. If by “it” you mean unit interfaces then, again, unit interfaces can only be implemented in . . . unit interfaces, of course.

    Please don’t construe my comments as a personal attack. I hope my response leads to greater understanding and not hurt feelings (as sometimes unfortunately happens).

    • jpluimers said

      I was trying to refer to ‘interface’ interfaces and ‘class’ interfaces, not ‘unit’ interfaces and the implementation using classes.
      Class interfaces can be either using abstract methods, or contain empty method implementations. Neither these two need extra units in the implementation uses lists.

      The reason for limiting it to that, is that large unit uses cycles are usually not caused by other things (like global procedures, or value types).

      So thanks for pointing at the ambiguity; I hope my reaction makes it more clear now.

      –jeroen

  3. Patrick McGovern said

    Hello! I don’t understand this statement:

    “Only if those options do not work, then start using Delphi SpeedUp by Andreas Hausladen.”

    I’ve found that SpeedUp is a great tool to have installed. I don’t have huge programs, but lots of medium sized ones. SpeedUp simply makes the IDE much more responsive. So my thought is, “So why not use it?”

  4. IL said

    What’s wrong with unit’s read-only attribute set? Did you mean source .pas files or compiled .dcu?
    By the way, Jedi VCS sets read-only for files that were checked-in.

    • jpluimers said

      It was with read-only source files.

      I’m not sure what is wrong; I’ve just seen that behaviour happen a few times in the past (I think it was pre 2007, but I’m not sure).
      I have not seen it in Delphi 2010.

      Since this post was meant as a general guideline for any Delphi version, I think it is important to address the read-only aspect as well.

      –jeroen

      • Andreas Hausladen said

        Older Delphi versions (pre 2007) open files in read/write mode. If the file is read-only an exception is raised by TFileStream.Create. This exception is caught and the file is opened in read-only mode. This alone slows down the file-open function because exceptions cost many CPU cycles. And with the introduction of Quality-Insight (the call stack) this got even worse because the CPU cycles for exception exploded.

  5. Andreas Hausladen said

    > Only if those options do not work, then start using Delphi SpeedUp

    Interesting logic. Fortunately I do not have such a logic ;-)

    • jpluimers said

      My point is that you should first narrow down the problem to something that can be fixed within the out-of-the-box Delphi install before resorting to other means.

      In my experience, adding Delphi SpeedUp after solving the original issue, improves it even more!

      –jeroen

      • Andreas Hausladen said

        > improves it even more

        DelphiSpeedUp mainly optimizes the IDE and the compiler’s interaction with the IDE. It doesn’t optimize the compiler’s algorithms. That what your “avoid large circular dependency groups” does.

      • IL said

        Thanks for recap! DelphiSpeedUp has a great use for my daily work on D7 mostly.

  6. Fritz Franz said

    My problem is that sometimes delphi turns to compile my project within 15 minutes. Normally it takes less then 30 seconds. When it takes that long the hard drive is fully engaged. Closing some applications sometimes helps.
    My system is Win XP Pro (newest patch level) with 3 GB RAM.
    I don’t think this issue can be resolved by your suggestions.
    Anyway thanks for your effort!
    Regards, Fritz

    • jpluimers said

      How much memory is Delphi using when the compile time increases to that much?

      –jeroen

    • Alistair Ward said

      hi,

      Our project recently blew out to about 45 minutes build time (~2000 units, 1.3million lines). I reduced this back to 3 minutes by refactoring 3 critical units.

      The critical units were all basically “container” units that held objects of many classes, and were in turn referenced by the implementation uses clauses of many other units.

      More concrete:

      I had a TProject in project.pas

      I changed this to a TProjectImplementation in ProjectImplementation.pas, and project.pas became:

      unit Project;

      interface

      uses
      ProjectImplementation;

      type
      TProject = class( TProjectImplementation )
      end;
      initialization
      end.

      This is the reverse of the suggestion (1) above, but is really easy to do and can be done without affecting other units.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

 
%d bloggers like this: