On 03/07/18 13:00, Bart wrote:
> On 03/07/2018 06:34, David Brown wrote:
>> On 02/07/18 22:44, Bart wrote:
>
>>> So, when people say that C++ is slow to compile (compared to equivalent
>>> code in other languages), then what is the reason?
>>>
>>
>> It is partly the complexity of the language (it is a lot harder to parse
>> than C), but mainly the large header files that need to be re-processed
>> for every compilation. The problem is not in the couple of lines of
>> "max" macro definition that gets re-processed - it is in the million
>> lines of standard library headers, boost, and other template libraries
>> that get re-processed.
>>
>> Thus improving this system - by separately built "modules" - is an
>> important area for the future of C++.
>>
>> Making "max" into an operator, on the other hand, is utterly irrelevant
>> from an efficiency viewpoint (either compiler efficiency, or generated
>> code efficiency).
>
> To use min and max the C++ way requires that these are defined as part
> of those libraries and thus their implementation code needs to be
> reprocessed for each compile whether it is used or not. And if it it is
> used, it requires that expansion (instantiation or whatever you call it).
Yes and no. For the std::min and std::max functions, you need to
#include <algorithm>. If you don't want anything from that header, you
don't include it and there is no cost. And if you do include that
header, then the cost for min and max is negligible - they are very
simple templates.
A reasonably complex C++ file often includes a good number of standard
library files. It is not uncommon for the compiler to be chewing
through several hundred thousand lines before getting to the user's
code. This /is/ an issue with C++ compilation - it is a known issue,
and work is being done to improve the matter with C++ modules.
(Pre-compiled headers can help, but have a lot of limitations.)
The three or four lines for "max" and "min" templates in this lot does
not matter. It is /irrelevant/ for compilation time. It is
/irrelevant/ for generating efficient code. It is a /good/ thing from
the point of view of language maintenance and development - the more of
the language that is in the library rather than the core language, the
easier it is to add new features, improve existing features, deprecate
bad features, and generally develop the language.
>
> It is this principle, applying to just about everything in the language
> not just max, then might be the reason for those huge headers.
>
There are many thousands of types, functions and templates in the C++
standard library. Do you think these should all be built-in parts of
the language?
> (FWIW I tried compiling 100,000 lines of 'a=MAX(a,b);', where MAX is the
> safe macro that someone posted, as C code with gcc -O0, and it crashed.
> But by extrapolation would have taken some 18 seconds. -O3 didn't crash
> and was much faster, but still much slower than compiling a=a+b;
>
> Elsewhere, I can compile 100K lines of 'a max:=b' in 0.25 seconds.)
>
If you find a use for a file consisting of 100,000 lines of "a = MAX(a,
b)", then please let us know.
>> It's okay to want a "max" operator because you think code would be
>> neater if it were an operator.
>
> That too. Slicker compilation is a bonus.
No, the slicker compilation is irrelevant.
>
> I can see also the attraction of implementing such things outside the
> core language, so that they can be applied to new user types more
> easily, but that seems to have a cost.
The attraction is real - the cost is not.
> However that doesn't stop binary
> + and - being built-in (I assume, in the case of C++) but still being
> applied to user types.
You have to have /something/ built in to the language. You need /some/
functions, operators, types as your fundamentals on which to build. You
pick these based on having the most necessary, common and convenient
features in the language - with other parts in the library. Thus
although multiplication could, in theory, be defined in terms of looped
additional and a smart optimiser, it makes sense to include such a
common operating in the core language. But "max" is rarely used, easily
defined in a library, and easily optimised by the compiler - there are
no advantages in putting it in the core.
If and when some of the more advanced proposals for C++ make it to the
language - reflection, modules, metaclasses - then a number of parts of
what is currently in the core language, could be done in libraries.
"class", "struct", "union", "enum" could all be part of a library rather
than being embedded in the language, leading to greater flexibility
(plus the downside - risk of greater complication and confusion). With
modules, this would not result in greater compile time.
>
>> Arguing that making "max" an operator would improve compile times
>
> Not just that by itself, no. Not unless the program consists of nothing
> but max's like my example above. But a program /could/ consist largely
> of things that do need to be expanded through things in those large
> headers, things that /might/ be built-in in another language.
>
I am sure there are things that /could/ be made more efficient by having
them in the core, rather than in the library - maybe even things that
would have a noticeable effect on efficiency (either of compilation, or
of the generated code). Compiler implementations certainly do this sort
of thing, with intrinsic functions or builtin functions. "max" is not a
serious candidate for such a thing.