Est-il pratique d'abandonner STL dans le développement C ++? [fermé]

19

Je sais que dans certains domaines (industrie du jeu par exemple), la STL n'est pas recommandée. Ma question est donc: est-ce vraiment une bonne pratique de ne pas utiliser STL dans certains cas? Si oui, quelles sont les principales raisons de ne pas utiliser la STL C ++ moderne?

CaptainJH
la source
question connexe
fredoverflow
certains de mes collègues soutiennent que l'itérateur rend le débogage plus difficile, car il n'est parfois pas facile d'intervenir, et cela s'applique également au lambda. Quelle est votre réponse?
CaptainJH
Quant à sauter des trucs pendant le débogage, voir, par exemple: stackoverflow.com/questions/2062881/…
Martin Ba
Cela semble être une bonne question. Peut-être que quelqu'un pourrait ajouter "Pourquoi un projet choisirait-il de ne pas utiliser la STL?"
Matthew James Briggs

Réponses:

25
  • Je ne peux penser qu'à une seule raison valable et c'est vraiment rare: difficile en temps réel. Beaucoup de choses dans la bibliothèque standard allouent de la mémoire en interne et ce n'est pas suffisamment déterministe pour les applications en temps réel difficiles, il faut donc les éviter. Ces applications sont généralement assez simples, bien qu'elles prennent un temps disproportionné à se développer en raison de l'examen et des tests très rigoureux.

  • Je peux penser à une raison invalide, mais très courante: les développeurs qui ne comprennent pas la complexité de calcul, abusent de STL puis blâment la bibliothèque.

    STL est généralement plus rapide au moment de l'exécution que les solutions de style C avec des pointeurs de rappel ou les solutions basées sur le polymorphisme avec des méthodes virtuelles ( voir également le keynote de Bjarne Stroustrup ). Cependant, lorsque le développeur ne comprend pas les spécifications de complexité données et abuse de la bibliothèque en créant quelque chose comme un vecteur de vecteurs de certains objets complexes (en C ++ 11, ce n'est plus un problème, cependant!), Cause un problème de performances et se défend avec "vous voyez, les vecteurs sont plutôt lents", cela peut donner l'impression que la bibliothèque standard est lente. Et une fois que les managers ont une telle perception, cela peut vivre très longtemps dans l'organisation.

  • De toute évidence, vous ne pouvez pas utiliser quoi que ce soit que la plateforme que vous ciblez ne prend pas en charge. Cependant, nous ciblons actuellement quatre plates-formes mobiles les plus courantes (Android, iOS, Bada et ancienne WinCE) et utilisons la bibliothèque standard et certaines parties de Boost sur chacune d'entre elles.

    Une grande partie de la bibliothèque standard n'était pas prise en charge par Microsoft au début de WinCE (les iostreams IIRC ne sont sortis qu'avec Visual Studio 2005), mais il était possible d'utiliser STLport bien avant cela. Et vous pouvez généralement obtenir cela pour compiler n'importe quoi. J'appellerais donc cette raison invalide également.

    D'ailleurs, pendant assez longtemps ce n'est pas "STL", mais la bibliothèque standard ANSI C ++. Il est défini par le même document standard qui définit la langue elle-même. Tout ce qui ne le prend pas en charge ne mérite pas vraiment d'être appelé C ++.

Jan Hudec
la source
6
Le premier argument (temps réel) n'est pas spécifique aux parties STL de la bibliothèque standard. sprintfalloue souvent aussi de la mémoire. Sur les plateformes en temps réel, les fonctions de bibliothèque standard ont également des limites déterministes. Cela rend les implémentations C ++ en temps réel difficiles: vous devez développer soigneusement toute une bibliothèque standard C ++, ce qui représente plus de travail que la petite bibliothèque standard C.
MSalters
@MSalters: Bien sûr, beaucoup de choses ne peuvent pas être utilisées en temps réel. Même certaines fonctionnalités de langage comme les exceptions ne le peuvent pas. Le C ++ est tout de même un excellent langage pour ces systèmes, car il peut combiner performances et contrôle précis avec de solides garanties (RAII est la caractéristique la plus importante pour cela).
Jan Hudec
@JanHudec: En effet, c'est pourquoi les parties STL ne sont nécessaires que pour les implémentations "hébergées" de C ++.
MSalters
7

J'utilise STL et boost depuis de nombreuses années déjà. Si je voulais l'abandonner et utiliser mes outils personnalisés, la motivation serait:

  1. Réduction du temps de compilation (75%). L'inclusion d'iostreams peut ajouter 1 million de lignes de code à votre module. Oui, les en-têtes précompilés aident beaucoup, mais cela ralentit toujours beaucoup la compilation dans les grands projets. À long terme, cela fait perdre beaucoup de temps à quiconque y travaille.
  2. Performance. (25%) STL est écrit pour fonctionner de manière générale, mais vous pouvez optimiser vos structures pour qu'elles fonctionnent exactement comme vous le souhaitez. Par exemple, vous pourriez avoir une structure de données avec des millions de chaînes courtes. Il pourrait être beaucoup plus rapide d'utiliser une classe de chaînes personnalisée basée sur le principe de boost :: small_vector (petit vecteur local statique de données, allocation dynamique uniquement pour les chaînes plus grandes), ce type de modifications peut rendre les sections critiques de code beaucoup plus rapides.
Marwin
la source
1
L'authentification unique est déjà courante.
Déduplicateur
pour la postérité: SSO -> optimisation des petites chaînes, c'est-à-dire que la plupart (toutes?) des implémentations std :: string gardent les petites chaînes sur la pile et passent au tas si besoin est
bleu
Le temps de compilation est important
user1754322
4

Il y a une bonne raison valable de ne pas utiliser la bibliothèque de modèles standard C ++: l'une de vos plates-formes cibles n'en a pas d'implémentation entièrement conforme (ou pas d'implémentation du tout) et vous savez qu'elle n'en obtiendra pas dans les prochaines années.

Patrick
la source
3
Aka "ne l'utilisez pas quand vous ne l'avez pas", ce qui est vraiment logique. :)
Xeo
4
Étant donné que la bibliothèque standard C ++ 03 est conçue pour être implémentée en termes de bibliothèque ANSI C89 uniquement, existe-t-il une plate-forme où vous ne pourriez pas obtenir au moins STLPort ?
Jan Hudec
@JanHudec Je crois qu'il existe des plateformes sans STL car elles n'ont pas assez de mémoire pour gérer le tout. Habituellement, il leur manque également d'autres fonctionnalités C ++ (par exemple des exceptions).
Sulthan
2
@Sulthan: Pour les microcontrôleurs, je comprends en quelque sorte, mais ceux-ci tombent généralement dans la catégorie "temps réel dur". Pour toute autre chose, ce sont principalement des idées préconçues, car STL est généralement tout aussi efficace en termes de mémoire et de performances que le code fabriqué à la main. Beaucoup d'inlining peut entraîner une plus grande binaire, mais cela pourrait même être évité par une mise en œuvre minutieuse à un certain coût de performance (qu'une solution artisanale aurait aussi). Les exceptions manquantes sont également soit des idées préconçues, soit de la paresse, car il faut un effort pour définir et mettre en œuvre l'exception ABI.
Jan Hudec
4

Je ne connais pas la complexité (efficacité de l'implémentation) mais j'utilise largement les conteneurs et les chaînes Qt au lieu des std et ils fonctionnent très bien. Je trouve également l'implémentation Qt des ensembles et des listes plus facile à utiliser.

Ainsi, il peut être pratique d'abandonner la STL si vous pouvez utiliser une autre bibliothèque qui correspond à vos besoins.

Giorgio
la source
2
les équivalents Qt ont été créés il y a bien longtemps quand aucune implémentation STL n'était a) disponible ou b) bonne. C'est la seule raison pour laquelle ils sont toujours utilisés, rien contre la STL d'aujourd'hui.
gbjbaanb
1
@Giorgio: le problème est dans les applications complexes, où vous combinez plusieurs bibliothèques. Les conteneurs STL, étant standard, forment une lingua franca . Plus précisément, ce sont leurs conventions qui le font. L'exemple le plus connu est Boost. Il peut fonctionner sur des conteneurs STL. il peut également fonctionner sur les conteneurs Qt, mais uniquement parce que Qt a QList<T>::iterator
suivi les
3
Je ne l'ai pas dévalorisé, mais je vois une raison: cela ne répond pas à la question. Vous avez dit qu'il y avait des choses à utiliser à la place de la STL, d'accord, mais ce n'est pas une raison pour éviter la STL. En outre, toute raison d'éviter STL s'applique probablement à Qt, MFC et à d'autres bibliothèques de ce type, voire plus.
Jan Hudec
3
@NoOne: Nous comprenons que vous êtes habitué au camelcase, pas au snakecase, mais cela n'empire pas ce dernier. Et parmi les trois noms de fonction que vous critiquez, le premier est parfaitement descriptif pour quiconque ayant quoi que ce soit à voir avec les chaînes c, et les deux autres sont hérités de C, ne discuteront pas de ceux-ci.
Déduplicateur
1
@NoOne: Comme je l'ai dit, je comprends parfaitement que vous êtes plus à l'aise avec CamelCase.
Déduplicateur
3

Patrick a évoqué la raison de ne pas utiliser l'intégralité de la STL, à savoir que votre ou vos plateformes n'en ont pas.

Dans l'ensemble, je pense que la question est sans objet. Ce n'est généralement pas une décision tout ou rien, mais une question de choix. Vous pouvez bien décider d'utiliser les conteneurs et les algorithmes, mais décidez d'utiliser quelque chose en dehors de Std Lib pour les chaînes et les E / S.

Martin Ba
la source
3

Ce n'est pas pratique, à moins qu'il y ait une raison lourde de le faire. Certaines de ces raisons auxquelles je peux penser ne comprennent qu'une implémentation partielle ou manquante de STL (ou toute autre partie de la bibliothèque standard) ou une limitation des ressources (mémoire, vitesse du processeur, stockage, ...) que vous devez contourner rouler vos propres outils qui adhèrent à ce que vous devez accomplir.

Dans l'industrie du jeu, la plupart des studios (même plus petits dans une certaine mesure) ont leurs bibliothèques internes et implémentent de nombreuses parties de bibliothèque standard qui sont hautement adaptées à la plate-forme cible et, dans certains cas, ciblent engnie ou même le jeu lui-même. Autrement dit, lors du développement d'un jeu pour consoles, le matériel est très limité par les normes d'aujourd'hui. Il y a des milliers et des milliers de lignes d'assemblage artisanal pour une raison. Il est très important de minimiser toutes sortes d'empreintes de ressources dans votre code afin que le jeu s'exécute plus rapidement, ce qui permet plus de contenu dans le monde du jeu (ou un monde plus grand par exemple), ce qui, espérons-le, aboutit à un meilleur produit.

"Chaque jeu réussi commence par déployer votre propre implémentation de liste chaînée."

zxcdw
la source
1
J'imagine que chaque jeu réussi commence par écrire du code à l'aide de la bibliothèque standard, puis n'optimiser le code qu'une fois le jeu largement profilé. L'optimisation avant d'avoir des données de profilage indiquant ce qui doit être optimisé est inutile.
Cromulent
Vrai. La dernière phrase était juste un jeu sur la façon "ancienne" d'écrire des jeux au début des années 90, quand le C ++ n'était pas aussi largement déployé et que l'assemblage + C était la voie à suivre. J'aurais peut-être dû clarifier les choses. Cela s'applique bien à l'industrie du jeu dans les consoles, cependant, la plupart des algorithmes et des structures de données sont écrits à la main par défaut parce que chaque octet et cycle compte (oui, même au détriment de la maintenabilité / portabilité / peu importe).
zxcdw
2
Il faut dire que c'est plutôt une vieille expérience de vivre. L'optimiseur moderne générera généralement un meilleur assemblage à partir d'un code simple et maintenable que le programmeur ne fera à la main et les modèles génériques comme dans STL ou Boost sont souvent en ligne pour un code aussi efficace que le casage spécial tout à la main. Mais il y a beaucoup de code qui a commencé à une époque où ce n'était pas le cas et beaucoup de gens qui ont appris le métier à l'époque et continuent à travailler de cette façon même si cela n'a plus de sens.
Jan Hudec
2
@JanHudec Le fait est que les implémentations (et les comportements aussi, en fait) doivent être très adaptés à la tâche. Vous ne pouvez tout simplement pas épargner quelques dizaines d'octets ici et là (ruiner la localité de référence), déposer quelques branches pour valider l'entrée (erreurs de prédiction de branche et échecs de cache d'instructions) et supposer que le compilateur sait comment vectoriser vos structures de données de manière optimale pour profiter de SIMD (ce ne sera pas le cas, ou du moins vous devez vérifier que ce qu'il tente est correct). Bien sûr, l'écriture de logiciels en temps réel sur un PC n'est pas aussi stricte, vous pouvez toujours ajouter un processeur plus rapide. Pas dans les consoles.
zxcdw