Pour une raison qui est largement hors de propos, j'ai installé Delphi 7 à nouveau en si longtemps. Je dois dire que j'ai été complètement époustouflé - d'une certaine manière, je ne l'ai pas été depuis un certain temps. Ce n'est pas du tout ainsi que je me souviens des choses. L'installation a duré environ 30 secondes. Son lancement a pris 2 secondes et il a été immédiatement utilisable. Je peux appuyer sur "Exécuter" la seconde après son démarrage, et moins d'une seconde plus tard, le programme vierge est déjà visible et en cours d'exécution. Vive les ordinateurs tellement plus rapides!
Mais la raison pour laquelle j'ai été époustouflé comme ceci est parce que j'utilise généralement Visual Studio 2010, cela ne semble pas du tout accrocheur. Certes, Delphi 7 est un système beaucoup plus petit que Visual Studio 2010, mais il a l' apparence d'avoir toutes les choses là - bas vraiment nécessaire: une palette de commande, un concepteur de formulaire, un éditeur de code avec la complétion de code. Je me rends compte que le langage pourrait être plus simple, et l'achèvement du code pourrait être beaucoup moins puissant, et l'EDI pourrait ne pas être presque aussi extensible et riche en fonctionnalités, mais quand même: je ne comprends pas comment (c'est-à-dire par quel mécanisme) fait avoir de nombreuses fonctionnalités supplémentaires (que je n'ai peut-être même pas encore déclenchées) font qu'un système comme Visual Studio se sent toujours lent en comparaison.
Je voudrais demander aux personnes expérimentées dans l'utilisation de systèmes à l'échelle de Visual Studio: qu'est-ce qui les ralentit? S'agit-il des couches sur les couches d'abstractions nécessaires pour maintenir la base de code dans les capacités de compréhension humaine? Est-ce la quantité de code à parcourir? Est-ce la tendance moderne vers des approches permettant de gagner du temps au programmeur aux dépens (énormément énormes) des cycles d'horloge / du service d'utilisation de la mémoire?
la source
Réponses:
Astronautique architecturale
Visual Studio 2010 est basé sur Windows Presentation Foundation. Jetez un œil à la classe Button pour WPF. Il s'agit du 9e enfant d'une classe de base. Il a environ 5 pages de propriétés, méthodes et événements. Dans les coulisses, il a cinq autres pages de définitions de style qui décrivent ses coins magnifiquement arrondis et les transitions d'animation subtiles lorsqu'un curseur de la souris se déplace dessus. C'est tout pour quelque chose qui affiche fondamentalement du texte ou une image et produit un événement de clic lorsqu'il détecte qu'un bouton de la souris descend.
Arrêtez un programme comme Visual Studio à tout moment aléatoire. Regardez la trace de la pile. Il y a de fortes chances que vous ayez 20 niveaux de profondeur dans la pile des appels et que cinq DLL ont été chargées pour y arriver.
Maintenant, comparez ces deux choses avec Delphi. Je parie que vous trouvez qu'un bouton Delphi n'a que 20 propriétés, méthodes et événements. Je parie que l'IDE Delphi n'a qu'une trace de pile de 5-7 niveaux de profondeur. Parce que lorsque les ordinateurs étaient plus lents, vous ne pouviez tout simplement pas supporter les frais généraux de Visual Studio 2010 sans que l'IDE prenne 40 minutes pour démarrer :-)
Est-ce que l'un est meilleur que l'autre? Eh bien, je peux généralement dire à un programme Delphi quand il se charge car il semble plat, les couleurs sont coupées (8 bits peut-être?), Et il n'y a pas d'ombrage ou d'animation subtile. Je me sens juste «bon marché» ces jours-ci. Pas cher, mais rapide.
Sommes-nous mieux lotis? C'est une question pour les philosophes, pas pour les codeurs.
la source
Je pense que vous en avez deviné un certain nombre, mais j'aimerais offrir ce que je considère comme le plus gros facteur, ayant travaillé sur une base de code assez grande (je ne sais pas si elle est aussi grande que Visual Studio - était dans les millions de lignes de code catégorie et environ un millier de plugins) pendant environ 10 ans et des phénomènes d'observation se produisent.
C'est aussi un peu moins controversé car il n'entre pas dans les API ou les fonctionnalités de langage ou quelque chose comme ça. Celles-ci concernent les «coûts» qui peuvent engendrer un débat plutôt que les «dépenses», et je veux me concentrer sur les «dépenses».
Coordination lâche et héritage
Ce que j'ai observé, c'est qu'une mauvaise coordination et un long héritage ont tendance à entraîner beaucoup de déchets accumulés.
Par exemple, j'ai trouvé une centaine de structures d'accélération dans cette base de code, dont beaucoup sont redondantes.
Nous aimerions avoir un arbre KD pour accélérer un moteur physique, un autre pour un nouveau moteur physique qui fonctionnait souvent en parallèle avec l'ancien, nous aurions des dizaines d'implémentations d'octrees pour divers algorithmes de maillage, un autre arbre KD pour le rendu , cueillette, etc., etc., etc. Ce sont toutes de grandes structures d'arbres volumineuses utilisées pour accélérer les recherches. Chaque individu peut prendre des centaines de mégaoctets en gigaoctets de mémoire pour une entrée de taille très moyenne. Ils n'étaient pas toujours instanciés et utilisés tout le temps, mais à tout moment, 4 ou 5 d'entre eux pouvaient être en mémoire simultanément.
Maintenant, tous ces éléments stockaient exactement les mêmes données pour accélérer leur recherche. Vous pouvez l'imaginer comme une ancienne base de données analogique qui stocke tous ses champs dans 20 cartes / dictionnaires / arbres B + redondants différents à la fois, organisés de manière identique par les mêmes clés, et les recherche tout le temps. Maintenant, nous prenons 20 fois plus de mémoire et de traitement.
De plus, en raison de la redondance, il y a peu de temps pour optimiser l'un d'eux avec le prix de maintenance qui l'accompagne, et même si nous le faisions, cela n'aurait que 5% de l'effet idéalement.
Qu'est-ce qui cause ce phénomène? Une mauvaise coordination était la cause numéro un que j'ai vue. Beaucoup de membres de l'équipe travaillent souvent dans leurs écosystèmes isolés, développant ou utilisant des structures de données tierces, mais n'utilisant pas les mêmes structures que les autres membres de l'équipe utilisaient même s'ils étaient des doublons flagrants des mêmes préoccupations.
Qu'est-ce qui fait que ce phénomène persiste? L'héritage et la compatibilité étaient la cause numéro un que j'ai vue. Comme nous avons déjà payé le coût de la mise en œuvre de ces structures de données et que de grandes quantités de code dépendaient de ces solutions, il était souvent trop risqué d'essayer de les consolider en moins de structures de données. Même si bon nombre de ces structures de données étaient très redondantes sur le plan conceptuel, elles n'étaient pas toujours proches de l'identique dans leur conception d'interface. Les remplacer aurait donc été un grand changement risqué au lieu de les laisser consommer de la mémoire et du temps de traitement.
Efficacité de la mémoire
En règle générale, l'utilisation de la mémoire et la vitesse ont tendance à être liées au moins au niveau global. Vous pouvez souvent repérer les logiciels lents par la façon dont ils accaparent la mémoire. Ce n'est pas toujours vrai que plus de mémoire conduit à un ralentissement, car ce qui compte, c'est la mémoire «chaude» (quelle mémoire est consultée en permanence - si un programme utilise une charge de mémoire mais seulement 1 mégaoctet est utilisé tout le temps, alors ce n’est pas un problème de vitesse).
Vous pouvez donc repérer les porcs potentiels en fonction de l'utilisation de la mémoire la plupart du temps. Si une application prend des dizaines à des centaines de mégaoctets de mémoire au démarrage, elle ne sera probablement pas très efficace. Des dizaines de mégaoctets peuvent sembler petits lorsque nous avons des gigaoctets de DRAM de nos jours, mais les caches de processeur les plus grands et les plus lents sont toujours dans la plage de mégaoctets minables, et les plus rapides sont toujours dans la plage de kilo-octets. Par conséquent, un programme qui utilise 20 mégaoctets juste pour démarrer et ne rien faire utilise en fait assez "beaucoup" de mémoire du point de vue du cache du processeur matériel, surtout si les 20 mégaoctets de cette mémoire seront accessibles à plusieurs reprises et fréquemment pendant l'exécution du programme.
Solution
Pour moi, la solution consiste à rechercher des équipes plus coordonnées et plus petites pour créer des produits, celles qui peuvent en quelque sorte suivre leurs "dépenses" et éviter "d'acheter" les mêmes articles encore et encore et encore.
Coût
Je vais plonger dans le côté «coût» plus controversé juste un tout petit peu avec un phénomène de «dépenses» que j'ai observé. Si un langage finit par avoir un prix inévitable pour un objet (comme celui qui fournit une réflexion à l'exécution et ne peut pas forcer l'allocation contiguë pour une série d'objets), ce prix n'est cher que dans le contexte d'un élément très granulaire, comme un unique
Pixel
ouBoolean
.Pourtant, je vois beaucoup de code source pour les programmes qui gèrent une lourde charge (par exemple: gérer des centaines de milliers à des millions de cas
Pixel
ou desBoolean
instances) payant ce coût à un niveau aussi granulaire.La programmation orientée objet peut en quelque sorte exacerber cela. Pourtant, ce n'est pas le coût des "objets" en soi ou même la POO en faute, c'est simplement que ces coûts sont payés à un niveau si granulaire d'un élément minuscule qui va être instancié par des millions.
Voilà donc les autres phénomènes de «coûts» et de «dépenses» que j'observe. Le coût est de quelques sous, mais les sous s'additionnent si nous achetons un million de canettes de soda individuellement au lieu de négocier avec un fabricant pour un achat en gros.
La solution ici pour moi est l'achat "en gros". Les objets sont parfaitement bien, même dans les langues qui ont une étiquette de prix pour chacun à condition que ce coût ne soit pas payé individuellement un million de fois pour l'équivalent analogique d'une canette de soda.
Optimisation prématurée
Je n'ai jamais vraiment aimé le libellé utilisé par Knuth ici, car "l'optimisation prématurée" accélère rarement les programmes de production dans le monde réel. Certains interprètent cela comme «l'optimisation précoce», alors que Knuth signifiait davantage «l'optimisation sans les connaissances / l'expérience appropriées pour connaître son véritable impact sur le logiciel». Si quoi que ce soit, l'effet pratique d' une véritable optimisation prématurée va souvent au logiciel de faire plus lent , car la dégradation des moyens de maintenabilité , il y a peu de temps pour optimiser les chemins critiques qui comptent vraiment .
C'est le dernier phénomène que j'ai observé, où les développeurs tentaient d'économiser des sous sur l'achat d'une seule canette de soda, pour ne plus jamais acheter, ou pire, une maison, perdaient tout leur temps à pincer des sous (ou pire, des sous imaginaires de ne pas comprendre leur compilateur ou l'architecture du matériel) alors qu'il y avait des milliards de dollars dépensés inutilement ailleurs.
Le temps est très limité, donc essayer d'optimiser les absolus sans avoir les informations contextuelles appropriées nous prive souvent de la possibilité d'optimiser les endroits qui comptent vraiment, et donc, en termes d'effet pratique, je dirais que "l'optimisation prématurée rend le logiciel beaucoup plus lent. "
Le problème est qu'il existe des types de développeurs qui prendront ce que j'ai écrit ci-dessus à propos des objets et essaieront d'établir une norme de codage qui interdit la programmation orientée objet ou quelque chose de fou de ce genre. Une optimisation efficace est une priorisation efficace, et cela ne vaut absolument rien si nous nous noyons dans une mer de problèmes de maintenance.
la source
--force
par des managers qui crient "vous serez viré si vous ne l'implémentez pas d'ici demain" qui emportent des années de bonnes pratiques d'ingénierie logicielle, de TDD, de tests unitaires et de tout principe de programmation humain et sain , plus deux autres fois où vous étiez fatigué .. ce gars qui a quitté l'entreprise fou parce qu'il a été licencié sans raison et a foiré la base de code .. ces bibliothèques abandonnées que vous n'avez jamais mises à jour ... et vous l'avez: délicieuse base de code spaghetti et les logiciels gonflés. Bon appétit