2010-11-18 48 views
0

Avec l'aide de la question Fast and flexible iterator for abstract class J'ai créé un GridIterator abstrait pour une classe abstraite GridData. Maintenant, je suis capable d'utiliser n'importe quelle sous-classe concrète de GridIterator pour parcourir n'importe quelle sous-classe concrète de GridData.Comment accélérer mon cours Iterator orienté objet?

Cependant, lors des tests, j'ai découvert que les opérateurs opérateur virtuel ++ et opérateur virtuel * devenaient de véritables goulots d'étranglement pour mes algorithmes. Je me demande s'il y a quelque chose que je peux faire pour l'accélérer. En raison de l'abstraction, inlining ne fonctionnera probablement pas pour moi? Je voudrais également fournir un Istator de const. Je ne suis pas sûr de savoir comment faire ce travail avec la conception de classe actuelle. En référence à ma question initiale (Fast and flexible iterator for abstract class), puis-je simplement créer un ConstGridIterator en tant que sous-classe à partir d'un itérateur avant STL avec const T au lieu de T? Ou dois-je implémenter une version const de chaque classe d'itérateur (GridIterator et baseImpl)?

Répondre

3

Faites comme la STL et n'utilisez pas de méthodes virtuelles dans un itérateur ou des conteneurs. La plupart des compilateurs, lorsqu'on leur demande d'optimiser, sont capables d'optimiser la plupart des itérateurs STL au point qu'ils sont complètement ignorés et qu'ils n'existent même pas dans le fichier objet. Par exemple, un *(vector<T>.begin()+5) pourrait être optimisé à vector<T>.__underlying_array[5] même si vector<T>::iterator est une classe complexe avec des constructeurs, des destructeurs et des redéfinitions d'opérateurs complexes.

Avoir un appel de méthode virtuelle partout dans la pile d'appel de operator++, begin(), end() ou operator !=() empêcher le compilateur d'optimiser cela correctement parce que la méthode pourrait être redéfinie par quoi que ce soit. Les méthodes virtuelles n'ont pas seulement un léger temps d'exécution, elles rendent le code inoptimisable en le rendant plus modulaire. Si vous voulez des performances, pensez à utiliser des modèles au lieu de l'héritage, ou modifiez votre compilateur, en disant que personne n'hérite de cette classe. Cela peut entrer en conflit avec votre conception actuelle, mais vous devez choisir deux priorités parmi ces trois: la performance, la modularité et le coût.