0
#include <chrono>
#include <iostream>

constexpr auto strlen_1(char const* sz) {
    auto const* p = sz;

    while (*p) {
        ++p;
    }

    return p - sz;
}

consteval auto strlen_2(char const* sz) {
    auto const* p = sz;

    while (*p) {
        ++p;
    }

    return p - sz;
}

int main() {
    using Clock = std::chrono::steady_clock;
    using Ms = std::chrono::milliseconds;
    using std::chrono::duration_cast;

    auto n = 0;
    auto start = Clock::now();
    {
        for (auto i = 0; i < 1000 * 10000; ++i) {
            n += strlen_1("abcdefghijklmnopqrstuvwxyz");
        }
    }
    auto stop = Clock::now();
    auto elapsed = duration_cast<Ms>(stop - start).count();
    std::cout << "strlen_1: " << elapsed << "ms" << std::endl;

    n = 0;
    start = Clock::now();
    {
        for (auto i = 0; i < 1000 * 10000; ++i) {
            n += strlen_2("abcdefghijklmnopqrstuvwxyz");
        }
    }
    stop = Clock::now();
    elapsed = duration_cast<Ms>(stop - start).count();
    std::cout << "strlen_2: " << elapsed << "ms" << std::endl;

    return n;
}

The output is:

strlen_1: 435ms
strlen_2: 18ms

See https://godbolt.org/z/zMTq64MME

Obviously, strlen_1 doesn't compute at compile-time, while strlen_2 does.

Why does constexpr not compute at compile-time for a string literal?

xmllmx
  • 39,765
  • 26
  • 162
  • 323
  • 4
    `constexpr` is *not* mandatory, you can use `n += std::integral_constant{};` to force it to execute at compile time and get the [same performance results](https://godbolt.org/z/4rE79f1bY) as `consteval`. – 康桓瑋 Dec 17 '21 at 02:56
  • Now that compiler has known the value at compile time, why not use it in this case? – xmllmx Dec 17 '21 at 02:59
  • 3
    It *can* be done at compile-time, but since it is *not* mandatory, the compiler *can* choose not to do it (to reduce computational overhead during compilation). – 康桓瑋 Dec 17 '21 at 03:19
  • 5
    This also shows the difficulty of trying to benchmark code compiled with optimizations turned off. In your Godbolt link if I go as far as `-O1`, it drops to 0ms for both methods. – Nathan Pierson Dec 17 '21 at 04:31
  • 1
    Compilers often don't evaluate contexpr code (if they don't have to for some reason) when optimisations are disabled – Alan Birtles Dec 17 '21 at 08:01

0 Answers0