URL: https://linuxfr.org/users/serge_ss_paille/journaux/memorisation-partielle-de-fonction-constexpr Title: Mémorisation partielle de fonction constexpr Authors: serge_sans_paille Date: 2018年09月25日T16:09:14+02:00 License: CC By-SA Tags: c++14 Score: 23 Demat'inal, Dans la lignée des expériences C++ que j'essaie de partager ici, je vous soumets ce bout de code qui m'a bien amusé : ```c++ template struct memoized { auto operator()(T v) const { static constexpr frozen::map cached = {{Vs, F{}(Vs)}...}; auto where = cached.find(v); if(where != cached.end()) { return where->second; } return F{}(v); } }; ``` Il utilise la bibliothèque [frozen](https://github.com/serge-sans-paille/frozen/pulls) qui fournit une version figée de quelques conteneurs standards. Un cas d'utilisation totalement abscons pourrait être ```c++ struct prime_sieve { constexpr bool operator()(uint64_t v) { if(v%2 == 0 && v != 2) return false; for(uint64_t i = 3, n = isqrt(v); i < v; i +=2) if(v % i == 0) return false; return true; } }; #include int main(int argc, char** argv) { memoized ps; std::cout << ps(7) << " " << ps(100) << "\n"; return 0; } ``` Que se passe-t-il donc ? Lors de la compilation, notre compilateur C++ préféré va initialisé la table ``cached`` qui est marquée ``constexpr``. Pour chacune des valeurs données en paramètre, il va donc appeler la fonction et stocker la valeur de retour dans la ``frozen::map``. Puis à l'exécution, lors d'un appel de fonction, il va faire une recherche (rapide, *frozen* implémente une recherche dichotomique presque sans branchement qui tire partie de la connaissance de la taille du tableau) dans cette table, renvoyer la valeur si elle est en cache, et à défaut, exécuter la fonction d'origine. Ça peut servir si, après mesure de performances, on se rend compte que certaines valeurs sont régulièrement utilisées. Voilà, je trouve l'idée amusante, je m'en servirai lors de la présentation que je donne [^1] cet après midi à CppCon, c'est donc une sorte de contenu exclusif LinuxFR :-) [^1]: stress stress

AltStyle によって変換されたページ (->オリジナル) /