Maison >développement back-end >C++ >Comment pouvons-nous optimiser l'implémentation « make_integer_sequence » de C 14 pour éviter l'épuisement de la mémoire ?
En C 14, le modèle d'alias make_integer_sequence a été introduit pour simplifier la création du modèle de classe integer_sequence. Pour implémenter make_integer_sequence, une structure d'assistance, make_helper, est utilisée.
template< class T, T... I> struct integer_sequence { typedef T value_type; static constexpr size_t size() noexcept { return sizeof...(I) ; } }; template< class T, T N> using make_integer_sequence = integer_sequence< T, 0,1,2, ... ,N-1 >; // only for illustration.
C'est ici que le problème se pose. Dans votre implémentation, la structure make_helper utilise une approche récursive. Bien que cela puisse sembler une solution simple, cela peut conduire à une augmentation rapide des instanciations de modèles, en particulier lorsque le paramètre N est grand.
template< class T, T N, T... I > struct make_helper { typedef typename mpl::if_< T(0) == N, mpl::identity< integer_sequence<T,I...> >, make_helper< T, N-1, N-1,I...> >::type; };
En raison de cette croissance exponentielle, le compilateur peut rapidement épuiser la mémoire virtuelle. , comme vous l'avez rencontré lorsque vous avez modifié la macro GEN pour générer des séquences entières avec des multiples de 4.
Le problème d'épuisement de la mémoire peut être résolu en utilisant une implémentation de profondeur logarithmique. Cette approche minimise le nombre d'appels récursifs, réduisant ainsi la profondeur d'instanciation du modèle.
template<unsigned...> struct seq{ using type = seq; }; template<class S1, class S2> struct concat; template<unsigned... I1, unsigned... I2> struct concat<seq<I1...>, seq<I2...>> : seq<I1..., (sizeof...(I1)+I2)...>{}; template<class S1, class S2> using Concat = Invoke<concat<S1, S2>>; template<unsigned N> struct gen_seq; template<unsigned N> using GenSeq = Invoke<gen_seq<N>>; template<unsigned N> struct gen_seq : Concat<GenSeq<N/2>, GenSeq<N - N/2>>{}; template<> struct gen_seq<0> : seq<>{}; template<> struct gen_seq<1> : seq<0>{};
Dans cette implémentation de profondeur logarithmique, la profondeur de récursion augmente de manière logarithmique avec N. Cela réduit considérablement la consommation de mémoire et permet la compilation de séquences entières avec des valeurs de N beaucoup plus grandes.
En utilisant l'implémentation de la profondeur logarithmique, le problème initial de l'épuisement de la mémoire virtuelle est résolu, permettant la génération de séquences entières avec de grandes valeurs de N.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!