Nous savons tous que l'optimisation prématurée est la racine de tous les maux, car elle conduit à un code illisible et difficile à mettre à jour. La pessimisation est encore pire, lorsque quelqu'un met en œuvre une "optimisation" parce qu'il pensez à il sera plus rapide, mais il finit par être plus lent, en plus d'être bogué, non maintenable, etc. Quel est l'exemple le plus ridicule que vous ayez vu à ce sujet ?
Réponses
Trop de publicités?Je pense que la phrase "l'optimisation prématurée est la racine de tous les maux" est beaucoup, beaucoup trop utilisée. Pour de nombreux projets, elle est devenue une excuse pour ne prendre en compte les performances que tardivement dans un projet.
Cette phrase est souvent une béquille pour les gens qui veulent éviter le travail. Je vois cette phrase utilisée alors que les gens devraient plutôt dire "Bon sang, nous n'avons vraiment pas pensé à cela dès le départ et nous n'avons pas le temps de nous en occuper maintenant".
J'ai vu beaucoup plus d'exemples "ridicules" de problèmes de performance stupides que d'exemples de problèmes introduits à cause de la "pessimisation".
- Lire la même clé de registre des milliers (ou des dizaines de milliers) de fois pendant le lancement du programme.
- Chargement de la même DLL des centaines ou des milliers de fois
- Gaspiller des méga-octets de mémoire en conservant inutilement les chemins d'accès complets aux fichiers.
- Ne pas organiser les structures de données de manière à ce qu'elles occupent beaucoup plus de mémoire qu'elles n'en ont besoin.
- Dimensionnement de toutes les chaînes de caractères qui stockent des noms ou des chemins de fichiers à MAX_PATH
- polling gratuit pour les choses qui ont des événements, des callbacks ou d'autres mécanismes de notification.
Ce que je pense être une meilleure déclaration est la suivante : "l'optimisation sans mesure ni compréhension n'est pas du tout une optimisation - c'est juste un changement aléatoire".
Un bon travail de performance prend du temps - souvent plus que le développement de la fonctionnalité ou du composant lui-même.
Les bases de données sont le terrain de jeu de la pessimisation.
Les favoris comprennent :
- Diviser un tableau en plusieurs parties (par plage de dates, plage alphabétique, etc.) parce qu'il est "trop grand".
- Créez une table d'archives pour les enregistrements retirés, mais continuez à l'UNION avec la table de production.
- Dupliquer des bases de données entières par (division/client/produit/etc.)
- Résistez à l'idée d'ajouter des colonnes à un index parce que cela le rend trop gros.
- Créez beaucoup de tableaux récapitulatifs parce que le recalcul à partir des données brutes est trop lent.
- Créez des colonnes avec des sous-zones pour gagner de l'espace.
- Dénormaliser en fields-as-an-array.
C'est ce qui me vient à l'esprit.
Je pense qu'il n'y a pas de règle absolue : certaines choses sont mieux optimisées dès le départ, d'autres non.
Par exemple, j'ai travaillé dans une entreprise où nous recevions des paquets de données provenant de satellites. Chaque paquet coûtant très cher, toutes les données étaient hautement optimisées (c'est-à-dire emballées). Par exemple, la latitude/longitude n'était pas envoyée sous forme de valeurs absolues (flottantes), mais sous forme de décalages par rapport au coin "nord-ouest" d'une zone "actuelle". Nous avons dû décompresser toutes les données avant de pouvoir les utiliser. Mais je pense que ce n'est pas une pessimisation, c'est une optimisation intelligente pour réduire les coûts de communication.
D'autre part, nos architectes logiciels ont décidé que les données décompressées devaient être formatées en un document XML très lisible et stockées dans notre base de données en tant que tel (au lieu de stocker chaque champ dans une colonne correspondante). Leur idée était que "XML est l'avenir", "l'espace disque est bon marché" et "le processeur est bon marché", et qu'il n'était donc pas nécessaire d'optimiser quoi que ce soit. Le résultat était que nos paquets de 16 octets étaient transformés en documents de 2 ko stockés dans une colonne, et que même pour des requêtes simples, nous devions charger des mégaoctets de documents XML en mémoire ! Nous recevions plus de 50 paquets par seconde, vous pouvez donc imaginer à quel point les performances sont devenues horribles (BTW, la société a fait faillite).
Donc, encore une fois, il n'y a pas de règle absolue. Oui, parfois l'optimisation trop précoce est une erreur. Mais parfois, la devise "le processeur, l'espace disque et la mémoire sont bon marché" est la véritable racine du mal.
Dans le cadre d'un ancien projet, nous avons hérité de quelques programmeurs de systèmes embarqués (par ailleurs excellents) qui avaient une expérience massive du Z-8000.
Notre nouvel environnement était un Solaris Sparc 32 bits.
Un des gars a changé tous les ints en shorts pour accélérer notre code, puisque saisir 16 bits de RAM était plus rapide que saisir 32 bits.
J'ai dû écrire un programme de démonstration pour montrer que la saisie de valeurs de 32 bits sur un système de 32 bits était plus rapide que la saisie de valeurs de 16 bits, et expliquer que pour saisir une valeur de 16 bits, l'unité centrale devait effectuer un accès à la mémoire de 32 bits, puis masquer ou décaler les bits non nécessaires pour la valeur de 16 bits.
Oh mon Dieu, je crois que je les ai tous vus. Le plus souvent, il s'agit d'un effort pour résoudre des problèmes de performance par quelqu'un qui est trop paresseux pour trouver la CAUSE de ces problèmes de performance ou même pour rechercher s'il y a réellement un problème de performance. Dans de nombreux cas, je me demande s'il ne s'agit pas simplement d'une personne qui veut essayer une technologie particulière et qui cherche désespérément un clou qui s'adapte à son nouveau marteau brillant.
Voici un exemple récent :
Un architecte de données vient me voir avec une proposition élaborée pour partitionner verticalement une table clé dans une application assez grande et complexe. Il veut savoir quel type d'effort de développement serait nécessaire pour s'adapter à ce changement. La conversation se déroule comme suit :
Moi : Pourquoi envisagez-vous de le faire ? Quel est le problème que vous essayez de résoudre ?
Lui : La table X est trop large, nous la partitionnons pour des raisons de performance.
Moi : Qu'est-ce qui vous fait penser qu'elle est trop large ?
Lui : Le consultant a déclaré qu'il y avait beaucoup trop de colonnes dans un seul tableau.
Moi : Et cela affecte les performances ?
Lui : Oui, des utilisateurs ont signalé des ralentissements intermittents dans le module XYZ de l'application.
Moi : Comment savez-vous que la largeur de la table est la source du problème ?
Lui : C'est la table clé utilisée par le module XYZ, et elle comporte environ 200 colonnes. Ce doit être le problème.
Moi (expliquant) : Mais le module XYZ en particulier utilise la plupart des colonnes de ce tableau, et les colonnes qu'il utilise sont imprévisibles parce que l'utilisateur configure l'application pour afficher les données qu'il veut afficher à partir de ce tableau. Il est probable que dans 95 % des cas, nous finissions par réunir toutes les tables, ce qui aurait pour effet de blesser performance.
Lui : Le consultant a dit qu'il était trop large et que nous devions le changer.
Moi : Qui est ce consultant ? Je ne savais pas que nous avions engagé un consultant, et ils n'ont pas du tout parlé à l'équipe de développement.
Lui : Eh bien, nous ne les avons pas encore engagés. Cela fait partie d'une proposition qu'ils ont faite, mais ils ont insisté sur le fait que nous devions ré-architecturer cette base de données.
Moi : Uh huh. Donc le consultant qui vend des services de re-conception de base de données pense que nous avons besoin d'une re-conception de base de données.....
La conversation s'est poursuivie ainsi. Par la suite, j'ai réexaminé la table en question et déterminé qu'elle pouvait probablement être réduite par une simple normalisation, sans qu'il soit nécessaire de recourir à des stratégies de partitionnement exotiques. Bien sûr, cela s'est avéré être un point discutable une fois que j'ai examiné les problèmes de performance (non signalés auparavant) et les ai attribués à deux facteurs :
- Index manquants sur quelques colonnes clés.
- Quelques analystes de données malhonnêtes qui verrouillaient périodiquement verrouillage des tables clés (y compris la table "trop large") en interrogeant les base de données de production directement avec MSAccess.
Bien sûr, l'architecte continue de faire pression pour un partitionnement vertical de la table en s'accrochant au méta-problème du "trop large". Il a même renforcé son argumentaire en obtenant une proposition d'un autre consultant en bases de données qui a pu déterminer que nous devions apporter des modifications majeures à la conception de la base de données sans regarder l'application ni effectuer la moindre analyse de performance.