Speed Up build by placing #pragma once at the correct place
We put our #pragma once in the header files at the wrong place.
We have to put it before the include guard defines, otherwise it does not have any purpose.
Better: Remove it.
It is not supported by all compilers as it is non-standard and modern compilers do the same optimization for the header guards as they would for #pragma once. I personally do like the #pragma once more but I guess compatibility is more important
modern compilers do the same optimization for the header guards as they would for
#pragma oncethats not true.
at least for gcc and Visual Studio using #pragma once has a significant impact. The fact is, the compiler does not need to continue parsing the whole file when reaching a #pragma once. otherwise the compiler always needs to do it even if the include guard afterwards will avoid double processing of the content afterwards.
oh and mostly only very old compilers or very specialized compiler do not have support for #pragma once
Sorry but that does not seem to be true
- For gcc it is measured to not matter: https://web.archive.org/web/20080930061318/http://www.gamesfromwithin.com/articles/0501/000067.html
- For VS 2003 it was around 20% faster
- "Yet, since include guards appear very often and the overhead of opening files is significant, it's common for compilers to optimize the handling of include guards, making them as fast as #pragma once" https://en.wikipedia.org/wiki/Pragma_once
- Cray compilers stopped supporting it: http://pubs.cray.com/content/S-2179/8.6/cray-c-and-c++-reference-manual-s-2179-86/miscellaneous-directives
As the cost of reintroducing header guards is exceptionally high I'd suggest not to remove them and instead rely on header guards and the compilers optimization for them
Newer measurements: https://tinodidriksen.com/2011/08/cpp-include-speed/
MSVC:
- Pragma only | 3.597
- Ifndef only | 5.153
GCC:
- Pragma only | 2.005
- Ifndef only | 0.309
Clang:
- Pragma only | 0.532
- Ifndef only | 0.568
This is for ~50000 files/30000 includes. Hence speed does not matter.
Edit: And order of ifndef+pragma does also not matter.
nobody spoke about removing the include guards. I don't know what they tested there, but here we definitly have an improvement since we used pragma once (and include guards) everywhere in the correct order - and also reordered all includes (perhaps the reason it got faster is the reordering) but that way every file was structured the same. Also if you have a quiet slow storage (i.e on virtual machines or similar) you have a significant speed increase with pragma + guard instead of guard+pragma
I will do it. I have seen that a lot of files have outdated or missing copyright headers anyway, so ...
nobody spoke about removing the include guards.
I'd rather not have both. The main advantage to me for #pragma once would be to not repeat things and reduce boilerplate which just adds noise when reading
I don't know what they tested there
I included the link. basically just including files
but here we definitly have an improvement since we used pragma once (and include guards) everywhere in the correct order
What is "here"? Is there really a (significant, measurable) benefit to using it? All other sources suggest not, so why spend work here?
Also if you have a quiet slow storage (i.e on virtual machines or similar) you have a significant speed increase with pragma + guard instead of guard+pragma
As written above and founded on sources: Clang+Gcc apply the same optimization on include guards as on pragma-once. So there is no difference there. So again: What is the foundation of that claim?
I will do it.
It's not about "lazyness" but on what is useful. Using both is rather disadvantageous to me.
I have seen that a lot of files have outdated or missing copyright headers anyway, so ...
Could you write a python script to update headers automatically? Do we need to use those lengthy headers or is a 1-2 liner maybe enough? Reducing the clutter and automating this (CI enforced?) would be great.
Here is "in my recent company project".
We have about 1.000.000 files to compile, so even if it has only a minimal amount of time for 50000 files, it will save a lot time for a million. We got the compile from 4h down to about 1h simply by reordering includes and adding the pragmas.
would be to not repeat things and reduce boilerplate which just adds noise when reading
Yeah, but the file has a header anyway so...
It's not about "lazyness"
thats not the point. I only wanted to tell you, that I will do it ;-)
Do we need to use those lengthy headers or is a 1-2 liner maybe enough?
theoretically a 3 liner should be sufficient:
// Copyright (c) 2005 - 2019 Settlers Freaks (sf-team at siedler25.org)
//
// This file is part of Return To The Roots.
//
// SPDX-License-Identifier: GPL-2.0-or-later
we still have to add some file with the "full" disclaimer text
We have about 1.000.000 files to compile, so even if it has only a minimal amount of time for 50000 files,
But "we" (in this project) have only 3k. So even the benefit of the 50k case is down by a factor of 10. So I doubt the time saved will even be in the seconds for a full recompile. I do like the pragma once if it saves the bike-shedding of the include guard naming (you changed a couple of them already. Gotta be quite some work to get them all in sync) and reduced maintenance/review time. Having/Requiring both increases the dev time for (in this case) no benefit
theoretically a 3 liner should be sufficient:
Yes please! :+1: (BTW: GPL 2? Isn't it 3?)
we still have to add some file with the "full" disclaimer text
-> https://github.com/Return-To-The-Roots/s25client/blob/master/COPYING
Found something useful for this: https://gcc.gnu.org/onlinedocs/cppinternals/Guard-Macros.html
TLDR: GCC optimizes for include guards unless anything but comments and whitespace is outside the guard
Anyway: I'd still like to use #pragma once only and don't care about compilers not supporting it if they still exist. It's just less work in creating and maintaining stuff...