0

It seems that constexpr evaluation, is just a extremely slow dynamic language. Everything is allocated on the heap (even scalar types), and garbage collected.

With msvc and gcc, this program takes up all my memory (clang doesn't), and takes multiple minutes to compile (msvc: 4m48s, clang: 3m34s, gcc: 3m39s, runtime: 0.001s).

#include <cstdint>

constexpr auto compute()
{
    auto a = int64_t{};
    for (int64_t i = 0; i < 100'000'000; i++)
        a += i;
    return a;
}

int main()
{
    static constexpr auto a = compute();
}

How do people stand the compile times? (even if they can be firewalled).

Is there anyway way to speed up compile times, using practices from dynamic languages?

Are there any performance improvements on the horizon?

I was hoping constexpr evaluation was a good way amortize heavy computation. But its not practical at the moment. I think I'm just going to write/read to/from a binary file instead. Perhaps if the compilation time of the translation unit in question was less than that of a clean build, multiple cores would make the compile times workable?

Compile commands:

g++ -std=c++23 main.cpp -fconstexpr-loop-limit=1000000001 -fconstexpr-ops-limit=68719476736

clang++ -std=c++2b -fconstexpr-steps=1100000000 main.cpp

Tom Huntington
  • 2,260
  • 10
  • 20
  • These times don't look right. – bolov Apr 07 '23 at 03:25
  • 3
    The trick is don't force the compiler to do millions of computations at compile time. If this heavy computation is supposed to resolve to a compile time constant (because of the constexpr) then you could always write a program to compute the constant and then hard code that value into your source code. – NathanOliver Apr 07 '23 at 03:43
  • @NathanOliver I'm actually computing an large array `N=20000`, that has to be done recursively or imperatively with nested loops. – Tom Huntington Apr 07 '23 at 03:47
  • Doing such heavy calculations with `constexpr` is not the usual use case. I would not expect compiler writers to give optimizing this high priority. Even if it was optimized, you don't usually want the compiler to spend on the order of seconds for individual constant expressions. They need to be reevaluated in each compilation and for each translation unit, but you normally need to recompile often during development. – user17732522 Apr 07 '23 at 03:51
  • @user17732522 you can expose a getter that returns a `const T&` to create a compilation firewall https://youtu.be/3aRZZxpJ_fc?t=661 – Tom Huntington Apr 07 '23 at 03:58
  • 3
    A likely cause is that compile time constexpr evaluations are required to check for UB. Thus, the simple expression `a += i` will have to test each time for overflow, which is UB. Even debug mode compiled code doesn't do this at runtime. – doug Apr 07 '23 at 05:26
  • *constexpr evaluation, is just a extremely slow dynamic language* - yes. Considering unbounded growth of language complexity compiler vendors are struggling with achieving correct evaluation, so evaluation speed does not seem to be a priority. – user7860670 Apr 07 '23 at 07:28
  • Bad algorithms are still bad for compile time calculation. Instead of fighting for better optimization and faster compilers, it may be very helpful to think about your algorithms! – Klaus Apr 07 '23 at 07:35
  • 1
    @TomHuntington Yes, but that's not the original use case of `constexpr`. It's original purpose is to allow easier calculation of constants needed as template arguments or in other compile-time only contexts. (The alternative was template metaprogramming which is even slower and more difficult to use.) In that case it can't be moved to a separate translation unit. – user17732522 Apr 07 '23 at 09:47
  • 1
    constexpr evaluation should be faster than template instantiation in most cases though – Mechap Apr 07 '23 at 19:28

1 Answers1

1

Jason Turner's new mental model was way off:

Yes, but that's not the original use case of constexpr. It's original purpose is to allow easier calculation of constants needed as template arguments or in other compile-time only contexts. (The alternative was template metaprogramming which is even slower and more difficult to use.) @user17732522

Jason did mention that clang might jit constexpr evaluation, but this is obviously didn't happen and is not even in the works. We haven't even got constexpr trig fuctions yet. So constexpr as it stands, remains just an ergonomic replacement for template metaprogramming.

Tom Huntington
  • 2,260
  • 10
  • 20