Existe-t-il des restrictions pratiques à l'utilisation de std :: string au lieu de tableaux de caractères et de std :: vector / list au lieu de tableaux en c ++?

StackOverflow https://stackoverflow.com/questions/801385

Question

J'utilise des vecteurs, des listes, des chaînes et des chaînes de manière obsessionnelle dans mon code. Y a-t-il des captures 22 impliquées qui devraient me rendre plus intéressé par l’utilisation occasionnelle de tableaux, de caractères et de wchars?

En gros, si vous travaillez dans un environnement prenant en charge la bibliothèque de modèles standard, est-il préférable d'utiliser les types primitifs?

Était-ce utile?

La solution

Pendant 99% des cas et pour 99% des mises en œuvre de la bibliothèque standard, vous constaterez que std :: vector est suffisamment rapide et que la commodité et la sécurité que vous en retirez l'emportent largement sur les coûts de performances.

Dans les cas très rares où vous avez vraiment besoin de code brut, vous pouvez traiter un vecteur comme un tableau de style C:

vector <int> v( 100 );
int * p = &v[0];
p[3] = 42;

La norme C ++ garantit que les vecteurs sont alloués de manière contiguë, ce qui garantit leur fonctionnement.

En ce qui concerne les chaînes, le facteur de commodité devient presque écrasant et les problèmes de performances ont tendance à disparaître. Si vous adonnez-vous aux chaînes de style C, vous revenez également à l'utilisation de fonctions telles que strlen (), elles-mêmes intrinsèquement très inefficaces.

En ce qui concerne les listes, vous devriez réfléchir à deux fois, et probablement à trois fois, avant de les utiliser, que ce soit votre propre implémentation ou la norme. La grande majorité des problèmes informatiques sont mieux résolus en utilisant un vecteur / tableau. Les listes de raisons qui apparaissent si souvent dans la littérature tiennent en grande partie au fait qu’elles constituent une structure de données commode pour les rédacteurs de manuels scolaires et de cours de formation à utiliser pour expliquer les pointeurs et l’allocation dynamique en une seule fois. Je parle ici en tant qu'ancien rédacteur de cours de formation.

Autres conseils

Je voudrais m'en tenir aux classes STL (vecteurs, chaînes, etc.). Ils sont plus sûrs, plus faciles à utiliser, plus productifs, avec moins de risque de fuites de mémoire et, autant que je sache, ils effectuent une vérification supplémentaire des limites à l’exécution, au moins au moment de DEBUG (Visual C ++).

Ensuite, mesurez les performances. Si vous identifiez que le ou les goulots d'étranglement se trouvent sur des classes STL, passez à l'utilisation de chaînes et de tableaux de style C.

De par mon expérience, les chances d’avoir un goulot d’étranglement sur l’utilisation de vecteurs ou de chaînes de caractères sont très faibles.

Un problème est la surcharge lors de l'accès aux éléments. Même avec un vecteur et une chaîne lorsque vous accédez à un élément par index, vous devez d'abord récupérer l'adresse du tampon, puis ajouter le décalage (vous ne le faites pas manuellement, mais le compilateur émet un tel code). Avec le tableau brut, vous avez déjà l'adresse du tampon. Cette indirection supplémentaire peut entraîner une surcharge importante dans certains cas et est soumise à un profilage lorsque vous souhaitez améliorer les performances.

Si vous n’avez pas besoin de réponses en temps réel, restez fidèle à votre approche. Ils sont plus sûrs que les caractères.

Vous pouvez parfois rencontrer des scénarios dans lesquels vous obtiendrez de meilleures performances ou une utilisation de la mémoire plus importante (par exemple, std :: string a généralement environ 24 octets de surcharge, 12 octets pour les pointeurs dans std :: string lui-même. et un bloc d’entête sur sa pièce allouée dynamiquement).

J'ai travaillé sur des projets où la conversion de std :: string en const char * enregistrait de la mémoire visible (10 en Mo). Je ne crois pas que ces projets soient ce que vous appelleriez typique.

Oh, utiliser STL va faire mal à votre temps de compilation, et à un moment donné cela peut poser problème. Lorsque votre projet génère plus de 1 Go de fichiers objets en cours de transmission à l'éditeur de liens, vous voudrez peut-être déterminer la quantité de modèles gonflés.

J'ai travaillé sur plusieurs projets où la surcharge de mémoire pour les chaînes est devenue problématique.

Cela vaut la peine de considérer à l'avance comment votre application doit évoluer. Si vous devez stocker un nombre illimité de chaînes, l'utilisation de const char * dans une table de chaînes gérée globalement peut vous faire économiser une énorme quantité de mémoire.

Mais généralement, utilisez certainement les types STL sauf s'il existe une très bonne raison de faire autrement.

Je pense que la technique d’allocation de mémoire par défaut est un tampon pour les vecteurs et que les chaînes allouent le double de la mémoire chaque fois que la mémoire actuellement allouée est utilisée. Cela peut être inutile. Vous pouvez bien sûr fournir un allocateur personnalisé ...

L’autre élément à prendre en compte est le rapport pile / tas. Les tableaux et les chaînes de taille statique peuvent être placés sur la pile, ou du moins le compilateur gère la gestion de la mémoire pour vous. Les compilateurs les plus récents gèreront pour vous des tableaux de taille dynamique s'ils fournissent la fonctionnalité C99 / C ++ 0x appropriée. Les vecteurs et les chaînes utiliseront toujours le tas, ce qui peut entraîner des problèmes de performances si vous avez des contraintes très strictes.

En règle générale, utilisez ce qui existe déjà à moins que votre projet ne soit gêné par sa vitesse / son coût en mémoire ... vous constaterez probablement que pour 99% des supports, les cours fournis par le STL vous permettent de gagner du temps et des efforts sans effort. impact sur les performances de vos applications. (c.-à-d. "éviter une optimisation prématurée")

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top