Hey Simon,

Thanks a lot for working on this! It's hard to notice the effect of
individual changes in this area, but in aggregate they can add up to a
significant build speed improvement.

Botond

On Mon, Dec 14, 2020 at 6:23 AM Simon Giesecke <sgiese...@mozilla.com> wrote:
>
>  tl;dr Build times on all platforms, in particular for incremental builds,
> have decreased in the last weeks by landing several cleanups to C++ include
> dependencies that reduce the aggregated number of included files by about
> 30%.
>
> Hi,
>
> Did you notice a reduction in build times lately? This might not be a
> coincidence. In this mail, I want to provide some details on the
> improvements made. I want to thank everyone who contributed to this through
> up-front discussions and reviews.
>
> Recently I landed a number of patches on Bug 1676346 [1] that in various
> ways clean up C++ include directives in our codebase. Some landed ca. 3
> weeks ago, some landed last week. Overall, these reduce the aggregated
> number of included non-system header files in a full build by about 30% on
> Linux. I don't have numbers for other platforms, but they should benefit as
> well. On my machine, this reduced the time for a clobber build by about
> 10%. While that might go unnoticed, incremental builds are often sped up
> even a lot more, since the number of translation units that need to be
> rebuilt decreases. E.g. the number of translation units that include
> dom/base/Document.h reduced by ca. 52%, resulting in a build time reduction
> of 48% on my machine after modifying that. Your mileage may vary.
>
> While this might not spare you from buying new hardware, it will make
> builds faster regardless of the hardware you are running on, and hopefully
> increase productivity. If you want to share your experiences with me,
> please get in touch!
>
> You might be curious what I did to achieve that, or how you can contribute
> to reducing build times yourself. It's a combination of things, most
> importantly three things:
> 1. Remove unused include directives
> 2. Split some headers
> 3. Use forward declarations more
> 4. Hide definitions to allow using forward declarations even more
>
> About 1: I found there are several include directives that are not needed
> at all. They could simply be removed. However, the majority of cases were a
> bit more complex, because of a lot of missing include directives. When
> removing an include for X.h from a header file Y.h that doesn't need it,
> another file that included Y.h might need X.h. Or, Y.h itself might need
> something from a header indirectly included from X.h. Or similar cases.
> This meant quite a lot of more include directives for more basic things
> needed to be added to ensure the build doesn't break.
>
> About 2: Some headers have a lot of dependencies, but only relatively few
> users of that header need them. One example was IPCMessageUtils.h, which is
> included by all files generated by IPDL, which also contained a lot of
> specializations of the ParamTraits template that are needed only by few
> files. Apart from some very basic specializations, these were moved to the
> new EnumSerializers.h and IPCMessageUtilsSpecializations.h as well as some
> existing headers, so that the remaining IPCMessageUtils.h header has only
> much more limited dependencies.
>
> About 3: Our coding style favors forward declarations over inclusion of the
> full definition of types where possible. I replaced the inclusion of header
> files containing full definitions of types by forward declarations at a
> number of places where this is sufficient, e.g. because they are only used
> in function signatures. It's worth noting that there were also a number of
> cases where a forward declaration was present, but actually the full
> definition is required, e.g. when a type is used as a base class or as the
> value type of a data member, or an inline function body dereferences into a
> member.
>
> About 4: As mentioned in the last point, inline function bodies often
> require the inclusion of additional headers because they dereference into
> types of which otherwise only forward declarations were necessary. Similar
> considerations apply to private (nested) classes. Some of those were moved
> to the corresponding implementation files to hide these dependencies, and
> reduce the number of necessary includes in the header files.
>
> I was using some tools to support this, notably ClangBuildAnalyzer [2] and
> include-what-you-use [3]. ClangBuildAnalyzer helped to detect headers that
> are expensive to parse throughout the build, and direct efforts to reduce
> those specifically. But there remains a long tail of similar things that
> can and should be fixed. include-what-you-use helps to identify the headers
> from which a file uses declarations to avoid depending on indirectly
> included files which might disappear from the include chain by unrelated
> changes. These tools are not readymade for everyday use, but I will try to
> provide some ideas for using them effectively later on.
>
> Best wishes
> Simon
>
> [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1676346
> [2] https://github.com/aras-p/ClangBuildAnalyzer
> [3] https://github.com/include-what-you-use/include-what-you-use
> _______________________________________________
> dev-platform mailing list
> dev-platform@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-platform
_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to