C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Will it slow the build time?

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
yuliy@gmx.de
Guest





PostPosted: Fri Dec 09, 2005 11:01 am    Post subject: Will it slow the build time? Reply with quote



Hello,

we all know there are compilation guards in headers, preventing compile
errors:
#ifndef XYZ
#define XYZ
......
#endif
With that ok, but I was told one of my older collegues that for
compilation speed, the guard macros must be added to cc files also.
Like:

#ifndef XYZ
#include "xyz.h"
#endif

The idea is that otherwise the compiler will spend much more time for
builkding. Especially in big projects.
I wonder, is it true? or maybe it was so with old compilers?

Thanks


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Hrayr BABAJANYAN
Guest





PostPosted: Fri Dec 09, 2005 3:12 pm    Post subject: Re: Will it slow the build time? Reply with quote



Hi!

If you do #include "xyz.h", preprocessor causes a replacement of the
#include "xyz.h" by the the entire contents of the file "xyz.h", and
(maybe there is some smart preprocessor optimization that I don't know)
only after that it processes the guard directives in newly added lines
of code (from the header file) and then skips the lines that are
protected by header guards. So your older colleague can be (or simply
is) right, if you protect the include directive from being processed
when the XYZ is already defined, it will save some preprocessing time
(time spent for replacement of the #include "xyz.h" directive by the
file "xyz.h", and this time can be significant if the "xyz.h" is large
enough).

Cheers!

--
Hrayr


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
benben
Guest





PostPosted: Fri Dec 09, 2005 3:15 pm    Post subject: Re: Will it slow the build time? Reply with quote



[email]yuliy (AT) gmx (DOT) de[/email] wrote:
Quote:
Hello,

we all know there are compilation guards in headers, preventing compile
errors:
#ifndef XYZ
#define XYZ
.....
#endif
With that ok, but I was told one of my older collegues that for
compilation speed, the guard macros must be added to cc files also.
Like:

#ifndef XYZ
#include "xyz.h"
#endif

The idea is that otherwise the compiler will spend much more time for
builkding. Especially in big projects.
I wonder, is it true? or maybe it was so with old compilers?]

The only reason why it should improve build time is that by this way the
compiler will not open xyz.h and process the first few tokens if and
only if xyz.h has already been included indirectly from other headers.

Unless you have a very slow file I/O on your build system the
improvement is marginal and it messes up the source. It is just not
worth the effort.

There are other ways to seriously speed up header processing such as
precompiling the headers.

Ben

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Mike Capp
Guest





PostPosted: Fri Dec 09, 2005 3:51 pm    Post subject: Re: Will it slow the build time? Reply with quote

[OP asked whether include guards should go in header files, source
files or both]

Putting guards in the header file prevents the compiler seeing the
definitions in that file more than once for a given translation unit.
It can improve build times, but as you say it's really about avoiding
errors.

Putting guards in the source file is an approach popularized by John
Lakos' book "Large-Scale C++ Design". (For many people it seems to be
the only thing adopted from that book.) The benefit is that this way
the compiler doesn't need to load and scan through a header just to
discover that it's all hidden by the guard; the degree of benefit
depends on the number and size of your headers. The downside is that it
makes your source rather ugly.

Is it worth it? Unless you're using an elderly and/or obscure compiler,
probably not. The Lakos book is quite old, and this advice has been
largely superseded by compiler improvements. GCC achieves the same
effect for you automagically; after scanning a header it remembers
whether the contents of that header are entirely contained by a guard
#ifndef/#define block, and won't re-read the file thereafter. I'm not
sure whether Visual C++ has the same behaviour by default, but there's
a "#pragma once" directive that will force it.

cheers,
Mike


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze
Guest





PostPosted: Fri Dec 09, 2005 3:51 pm    Post subject: Re: Will it slow the build time? Reply with quote

[email]yuliy (AT) gmx (DOT) de[/email] wrote:

Quote:
we all know there are compilation guards in headers,
preventing compile errors:
#ifndef XYZ
#define XYZ
.....
#endif

With that ok, but I was told one of my older collegues that
for compilation speed, the guard macros must be added to cc
files also.
Like:

#ifndef XYZ
#include "xyz.h"
#endif

The idea is that otherwise the compiler will spend much more
time for builkding. Especially in big projects. I wonder, is
it true? or maybe it was so with old compilers?

It depends on the compiler and the environment you're working
in. Some compilers, like g++, recognize the standard include
guard idiom, and don't even try to read the file a second time.
Otherwise, if the headers aren't too large, and you're working
from local disk, the difference in time is likely to be
unnoticeable. On the other hand, if your compiler doesn't
implement this optimization, and you're headers are on an NFS
mounted file system on a slow or overloaded network, it can make
a significant difference.

It's pretty easy to write a scrit which generates some dummy
files for both cases, and see if it makes a difference in your
environment. (Note, however, that even greater gains can often
be had by eliminating dependencies entirely. Things like using
a forward declaration of a class, rather than including the
header with its definition.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Ralf Fassel
Guest





PostPosted: Fri Dec 09, 2005 7:04 pm    Post subject: Re: Will it slow the build time? Reply with quote

* benben <benhongh (AT) yahoo (DOT) com.au>
Quote:
The only reason why it should improve build time is that by this way
the compiler will not open xyz.h and process the first few tokens if
and only if xyz.h has already been included indirectly from other
headers.

And how does the dumb preprocessor know where to stop ignoring things
after having read the starting #ifndef? Yes, it has to parse the
header file again, looking for the matching '#endif'.

This creates 20 header files, each one including all the previous
ones, and one C file including them all:

awk 'BEGIN {
print > "file.c"
for (i=0; i<20; i++) {
outfile="file" i ".h"
print > outfile
print "#ifndef FILE" i >> outfile
print "#define FILE" i >> outfile
for (k=0; k<i; k++) {
# REDUNDANT INCLUDE GUARD START, remove comment to activate
#print "#ifndef FILE" k >> outfile
print "#include "file" k ".h"" >> outfile
# REDUNDANT INCLUDE GUARD END, remove comment to activate
#print "#endif " >> outfile
}
print "#endif" >> outfile
print "#include "" outfile """ >> "file.c"
}
}'

On our local 100MB network, I get a measurable slow-down with the
Microsoft cl compiler when recursive headers are encountered
(Windows -> SMB share on Linux file server):

20 files
plain 0.907s
redundant 0.227s
50 files
plain 4.999s
redundant 0.476s
100 files
plain 19.524s
redundant 0.946s


I don't see this dramatic slow-down with gcc on the same directory
NFS-mounted on a linux box (it looks like gcc is _not_ skipping the
read step as indicated by James Kanze in another message in this
thread), so your mileage may vary.

R'

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Paul Floyd
Guest





PostPosted: Sat Dec 10, 2005 2:07 am    Post subject: Re: Will it slow the build time? Reply with quote

On 9 Dec 2005 06:01:22 -0500, [email]yuliy (AT) gmx (DOT) de[/email] <yuliy (AT) gmx (DOT) de> wrote:

[snip include guards, and redundant include guards]

The thing to do is to do some tests and measure the results. John Lakos'
book has already been mentioned, and IIRC he knocked up a script to
generate inclusions 1,2,3,... deep of 10,100,1000,... files, with and
without redundant include guards. He then measured the differences in
compile time.

In my experience, with older compilers (e.g., Sun CC 4.0), there was a
significant benefit. On the compilers that I use now (mainly Sun CC 5.7
and GCC 3) there is no measureable difference.

A bientot
Paul
--
Paul Floyd http://paulf.free.fr (for what it's worth)
Surgery: ennobled Gerald.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ron Natalie
Guest





PostPosted: Sat Dec 10, 2005 1:08 pm    Post subject: Re: Will it slow the build time? Reply with quote

Mike Capp wrote:
Quote:

Putting guards in the source file is an approach popularized by John
Lakos' book "Large-Scale C++ Design". (For many people it seems to be
the only thing adopted from that book.) T

Which is a shame because it's the most irrelevant parts of the book
(but Lagos seems to have an axe to grind about it so he devotes far
more time than it is worth to the subject). It's largely a workaround
for a implementation detail. At the best it just speeds up compile
time. While programmers bristle at the time it takes for automated
processes to run, it makes no difference to ultimate software quality
or maintainability.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
James Kanze
Guest





PostPosted: Sat Dec 10, 2005 9:37 pm    Post subject: Re: Will it slow the build time? Reply with quote

Ralf Fassel wrote:
Quote:
* benben <benhongh (AT) yahoo (DOT) com.au
| The only reason why it should improve build time is that by
| this way the compiler will not open xyz.h and process the
| first few tokens if and only if xyz.h has already been
| included indirectly from other headers.

And how does the dumb preprocessor know where to stop ignoring
things after having read the starting #ifndef? Yes, it has to
parse the header file again, looking for the matching
'#endif'.

This creates 20 header files, each one including all the
previous ones, and one C file including them all:

awk 'BEGIN {
print > "file.c"
for (i=0; i<20; i++) {
outfile="file" i ".h"
print > outfile
print "#ifndef FILE" i >> outfile
print "#define FILE" i >> outfile
for (k=0; k<i; k++) {
# REDUNDANT INCLUDE GUARD START, remove comment to activate
#print "#ifndef FILE" k >> outfile
print "#include "file" k ".h"" >> outfile
# REDUNDANT INCLUDE GUARD END, remove comment to activate
#print "#endif " >> outfile
}
print "#endif" >> outfile
print "#include "" outfile """ >> "file.c"
}
}'

(That's what I thought I should have done, but was too lazy to
do.)

Quote:
On our local 100MB network, I get a measurable slow-down with
the Microsoft cl compiler when recursive headers are
encountered (Windows -> SMB share on Linux file server):

20 files
plain 0.907s
redundant 0.227s
50 files
plain 4.999s
redundant 0.476s
100 files
plain 19.524s
redundant 0.946s

Just for the record, the network speed is only part of the
factor. My experience is that a lot depends on network load as
well.

Note too that this sort of thing increases network load. Not
only are your compiles slower, but you slow down everyone else
using the network.

Quote:
I don't see this dramatic slow-down with gcc on the same
directory NFS-mounted on a linux box (it looks like gcc is
_not_ skipping the read step as indicated by James Kanze in
another message in this thread), so your mileage may vary.

Something doesn't seem to hold together there. If you are not
seeing any slowdown, it is because g++ *IS* skipping the read
step.

--
James Kanze mailto: [email]james.kanze (AT) free (DOT) fr[/email]
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Ralf Fassel
Guest





PostPosted: Mon Dec 12, 2005 12:13 pm    Post subject: Re: Will it slow the build time? Reply with quote

* James Kanze <kanze (AT) none (DOT) news.free.fr>
Quote:
I don't see this dramatic slow-down with gcc on the same directory
NFS-mounted on a linux box (it looks like gcc is _not_ skipping
the read step as indicated by James Kanze in another message in
this thread), so your mileage may vary.

Something doesn't seem to hold together there. If you are not
seeing any slowdown, it is because g++ *IS* skipping the read step.

Most probably you're right, and most probably it does not make such a
big difference in many cases.

First, if I insert #warnings as first thing in the header, I see (of
course) the recursive inclusions of the headers with gcc:

In file included from file.c:2:
file0.h:2:2: warning: #warning FILE0

In file included from file.c:3:
file1.h:2:2: warning: #warning FILE1
In file included from file1.h:5,
from file.c:3:
file0.h:2:2: warning: #warning FILE0

In file included from file.c:4:
file2.h:2:2: warning: #warning FILE2
In file included from file2.h:5,
from file.c:4:
file0.h:2:2: warning: #warning FILE0
In file included from file2.h:6,
from file.c:4:
file1.h:2:2: warning: #warning FILE1
...

Second, of course, this means that I don't get the automagic any more,
since the header is not completely wrapped any more. (For the timings
below, it makes little difference whether I put the #warning here or a
#undef foo/#define foo).

But even then, though I see a slow-down between with and w/o #warning,
it is not that dramatic as in the Windows->SMB scenario in cases where
'few' files are involved. The timings are then (warnings redirected
to /dev/null, Suse 9.3 NFS -> Redhat 3 Server, ext3):

20 files
w/ warn w/ redundant 0.036s
w/ warn w/o redundant 0.041s
w/o warn w/ redundant 0.039s
w/o warn w/o redundant 0.043s

50 files
w/ warn w/ redundant 0.051s
w/ warn w/o redundant 0.072s
w/o warn w/ redundant 0.050s
w/o warn w/o redundant 0.067s

100 files
w/ warn w/ redundant 0.065s
w/ warn w/o redundant 0.195s
w/o warn w/ redundant 0.060s
w/o warn w/o redundant 0.057s-0.176s

500 files
w/ warn w/ redundant 0.296s
* w/ warn w/o redundant 11.695s
w/o warn w/ redundant 0.291s
* w/o warn w/o redundant 0.410s

So it seems it makes a measurable difference only for large include
trees. The two cases marked (*) in the last block show where gcc
obviously skips the recursive inclusion in the second case, since all
header contents is guarded by the #ifdef then (in the first case it
has to process the contents which is outside the include guard).

R'

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
kanze
Guest





PostPosted: Tue Dec 13, 2005 6:36 pm    Post subject: Re: Will it slow the build time? Reply with quote

Ralf Fassel wrote:
Quote:
* James Kanze <kanze (AT) none (DOT) news.free.fr
I don't see this dramatic slow-down with gcc on the same
directory NFS-mounted on a linux box (it looks like gcc is
_not_ skipping the read step as indicated by James Kanze
in another message in this thread), so your mileage may
vary.

Something doesn't seem to hold together there. If you are
not seeing any slowdown, it is because g++ *IS* skipping the
read step.

Most probably you're right, and most probably it does not make
such a big difference in many cases.

Well, I'm very sure that g++ does do the optimization. It was
the first compiler to do so. For the rest: how much it makes a
difference depends on many factors. I suspect that if all of
the files are locally mounted, it doesn't make a big difference.
If the files are remote mounted, and the network is overloaded,
it will make a difference.

Quote:
First, if I insert #warnings as first thing in the header, I
see (of course) the recursive inclusions of the headers with
gcc:

In file included from file.c:2:
file0.h:2:2: warning: #warning FILE0

In file included from file.c:3:
file1.h:2:2: warning: #warning FILE1
In file included from file1.h:5,
from file.c:3:
file0.h:2:2: warning: #warning FILE0

In file included from file.c:4:
file2.h:2:2: warning: #warning FILE2
In file included from file2.h:5,
from file.c:4:
file0.h:2:2: warning: #warning FILE0
In file included from file2.h:6,
from file.c:4:
file1.h:2:2: warning: #warning FILE1
...

Second, of course, this means that I don't get the automagic
any more, since the header is not completely wrapped any more.

Of course not. The standard says that the #warning must be
seen, so g++ ensures that it is seen. All you can add outside
the wrapper is white space and comments.

Note that g++ also notes the condition, and verifies that it
hasn't changed -- add an undef, and you'll get the file a second
time.

Quote:
(For the timings below, it makes little difference whether I
put the #warning here or a
#undef foo/#define foo).

But even then, though I see a slow-down between with and w/o
#warning, it is not that dramatic as in the Windows->SMB
scenario in cases where 'few' files are involved.

Well, the environment isn't the same. If the files are mounted
locally, it obviously isn't the same. If they're on a different
network, what are the loads. For that matter, it's quite
possible that NFS is faster than SMB (or vice versa).

About all you can say is that the optimization will never result
in slower builds. And that there will be cases when it makes a
significant difference.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.