• [^] # Re: et avec les fold-expressions ?

    Posté par . En réponse au journal Constexpr versus template. Évalué à 3.

    Je tente un petit benchmark vite fait, et au passage je compare aussi variable template vs. fonction.

    #include <utility>
    #ifdef USE_TEMPLATE
    template <int N>
    constexpr int count = [](){
     int s = 0;
     for (int i = 1; i <= N; ++i)
     s += i;
     return s;
    }();
    #define COUNT(n) count<n>
    #elif USE_FUNCTION
    constexpr int count(int n) {
     int s = 0;
     for (int i = 1; i <= n; ++i)
     s += i;
     return s;
    }
    #define COUNT(n) count(n)
    #elif USE_FOLD
    template <typename T>
    struct count_impl;
    template <int... Ints>
    struct count_impl<std::integer_sequence<int, Ints...>>
    {
     static constexpr int value = (0 + ... + Ints);
    };
    template <int N>
    constexpr int count = count_impl<std::make_integer_sequence<int, N+1>>::value;
    #define COUNT(n) count<n>
    #endif
    int main() {
     { int array[COUNT(1)]; }
     // ...
    }

    Je crée des tableaux de taille COUNT(1) jusqu'à COUNT(800), puis 1000 de plus avec COUNT(100). J'utilise g++ 11.0.1 et clang++ 12.0.0. Les temps sont des moyennes pifométriques calculées après quelques essais.

    • g++: TEMPLATE → 530ms, FUNCTION → 450ms, FOLD → 15s
    • clang++: TEMPLATE → 540ms, FUNCTION → 600ms, FOLD → instantiating fold expression with 257 arguments exceeded expression nesting limit of 256

    Ce genre d'utilisations de fold expressions est clairement une mauvaise idée. Entre variable et fonction, la différence est moins nette et dépend du compilateur, donc pas de vainqueur.