Question

De retour dans les « jours de bonne ol », » quand nous copier shareware sur disquettes pour des amis, nous avons également utilisé un peu de juste de réunion. Il y avait une pratique courante de « micro-optimisation », où vous regarder et regarder les lignes de montage jusqu'à ce que vous a trouvé un moyen d'exprimer dans une instruction moins. Il y avait même un dicton qui était mathématiquement impossible, que « Vous pouvez toujours supprimer une instruction plus. » Étant donné que la modification de la performance d'exécution par de petits facteurs constants est pas un problème majeur pour aujourd'hui la programmation (plus) , sont des programmeurs transfert de ces efforts micro-optimisation ailleurs?

En d'autres termes, une meilleure pratique peut être prise à un état extrême où il n'y a plus rien ajouter de la valeur? Et au lieu de perdre du temps est?

Par exemple: Do perdre du temps des programmeurs généralisante méthodes privées qui ne sont appelés d'un endroit? de perte de temps réduit les données de cas de test? Sont des programmeurs (encore) trop préoccupés par la réduction des lignes de code?

Il y a deux grands exemples de ce que je suis à la recherche ci-dessous: (1) Passer du temps à trouver les noms de variables à droite, même tout changement de nom; et (2) Retrait même mineure et la duplication du code ténu.


Notez que ceci est différent de la question « Que pouvez-vous optimiser pour? », parce que je demande ce que les autres programmeurs semblent optimiser, avec la stigmatisation de ces optimisations étant « micro », et donc pas une utilisation productive du temps.

Était-ce utile?

La solution

Mise en forme de code

Don't     get    me   wrong             ,
code      should be   consistent        & 
readable                                , 
but       some   take it         too far.

Autres conseils

Je l'habitude d'écrire beaucoup de retour assembleur dans la journée. Il est non seulement que les statisticiens ont obtenu mieux, il est que la plupart du matériel a maintenant beaucoup de logique consacrée à l'extérieur de commande exécution de code. Le véritable micro-question est la planification, la plupart des instructions d'ordinateur prennent plusieurs horloges de la machine pour produire un résultat -et une charge de mémoire cache misses peut prendre plusieurs centaines! L'idée était donc de planifier d'autres instructions pour faire quelque chose d'utile, au lieu d'attendre un résultat. Et les machines modernes peuvent émettre plusieurs instructions par période d'horloge. Une fois que nous avons commencé à l'exécution hors ordre HW, je trouve que d'essayer d'obtenir d'excellentes performances avec la main le codage est devenu un jeu de tasses. D'abord la HW hors ordre ne serait pas exécuter les instructions de votre commande conçu avec soin, la fantaisie nouvelle architecture HW a réduit la peine de suffisamment de planification du logiciel inoptimal que le compilateur était habituellement dans quelques pour cent de votre performance. De plus, je trouve que les compilateurs exécutaient maintenant bien connu, mais des tours génératrices de complexité, tels que le déroulement, chargement par le bas, le logiciel pipelining, etc. En bout de ligne, vous devez travailler vraiment très dur, sauter certains de ces astuces et le compilateur vous bat. Utilisez-les tous et le nombre d'instructions assembleur vous avez besoin d'augmenter plusieurs fois!

Probablement plus important encore, la plupart des problèmes de performance, ne sont pas sur les taux d'émission d'instruction, mais l'obtention des données dans la CPU. Comme je l'ai mentionné plus haut, la latence de la mémoire est maintenant des centaines de cycles, et la CPU peut exécuter plusieurs instructions par période d'horloge, de sorte à moins que le programme -et en particulier les structures de données sont conçus de telle sorte que le taux de succès de cache est extrêmement élevé, au niveau micro-accord d'instruction aura pas gain. Juste comme types militaires disent amateurs parlent tactiques, les pros parlent la logistique. la programmation de la performance est maintenant plus de 90% de la logistique (données en mouvement). Et cela est difficile à quantifier, la gestion de la mémoire moderne a généralement plusieurs niveaux de cache, et les pages de mémoire virtuelle sont gérées par une unité matérielle appelé TLB. Aussi l'alignement des adresses lowlevel devient important, en tant que données réelles les transferts, ne sont pas en unités d'octets, ou même 64bit à long-longs, mais ils viennent en unités des lignes de cache. Ensuite, les machines les plus modernes ont du matériel qui tente de prédire ce qui manque la ligne cache vous pourriez avoir besoin dans un avenir proche et émettre prélectures automatiques pour les obtenir dans le cache. Donc, la réalité est que les modèles de performance processeurs modernes sont si complexes qu'il est presque non compréhensible. Même les simulateurs de matériel détaillés ne peuvent jamais correspondre à la logique exacte des puces, donc exacte accord est tout simplement impossible plus.

Il y a encore une place pour une main de codage. bibliothèques mathématiques (comme dire la fonction exp), de même que les opérations d'algèbre linéaire plus importants (comme la matrice de multiplication) sont encore généralement codés main par des experts qui travaillent pour le fournisseur de matériel (à savoir Intel ou AMD ou IBM), mais ils ont probablement seulement besoin d'un couple de programmeurs en assembleur de premier ordre par méga-ordinateur corp.

Je passe parfois (déchets?) Temps tout en choisissant un bon nom pour une variable ou une méthode de sorte qu'il est non seulement avec précision descriptive, mais a aussi un bon style linguistique.

Il va un peu plus loin lorsque je tente de mettre l'ensemble des travaux (un programme) dans le même style linguistique. Parfois, mes changements d'opinion et je révise le livre. :)

Non qu'il faut beaucoup de temps. Il est assez rare. Mais je tiens à garder la bonne grammaire dans mes programmes.

complexité temps. Je passe beaucoup trop de temps pour optimiser les choses pire performance de cas sur une échelle qui est des ordres de grandeur plus grand que tout ce que je sais le programme rencontrerai réaliste.

Je suis tout simplement trop obsessionnelle de lâcher du « mais pourrait développer ce grand » os, même lorsque d'autres décisions de conception empêchent que de façon réaliste qui se passe.

Cependant, pour ma défense, si le irréaliste devenir réalité .. l'optimisation est vraiment pas « micro » plus longtemps. Remarque, je ne dis pas impossible , mais irréaliste .

Bien sûr, les exigences ont priorité.

Je pense que j'ai semaines gaspillée valeur de temps à tripoter les gestionnaires Java d'exception.

Il est beaucoup de travail pour le code qui échoue deux ou trois fois par an. Si cela est un avertissement ou une info? Erreur fatale ou? Est-il vraiment fatal est le processus sera re-donné naissance en cinq minutes? Est-il vraiment un avertissement si tout est toujours en état par défaut?

Beaucoup de discussion et regardant fixement le nombril sur la nature d'une erreur IO. Si vous ne pouvez pas lire un fichier sur le réseau, est une erreur de fichier ou d'une erreur de réseau? Et ainsi de suite.

À un moment donné, j'ai remplacé toutes les chaînes de concat avec String.format si l'erreur de fichier annuel ne se traduit pas par des objets supplémentaires dans le tas. C'était un déchet.

Je suppose que je suis préoccupé par les lettres de crédit trop. Pas tellement, mais eux-mêmes les lettres de crédit plutôt nombre de déclarations et même plus le nombre de déclarations en double. Je suis allergique à la duplication de code. En général refactoring d'amour I, mais je suppose que 50% de ce que je fais ne fait pas le code signifficantly plus agréable.

Lecture d'un fichier ligne par ligne au lieu de simplement lire la ligne entière dans une chaîne et traiter la chaîne en une seule prise.

Bien sûr, cela fait une différence dans la vitesse d'exécution, mais est rarement la peine les lignes de code supplémentaires. Il rend le code beaucoup moins maintenable et augmente la taille du code.

Oui, cela n'a probablement pas de sens si le fichier est 3Go grand, mais la plupart des fichiers ne sont pas si grand (au moins pas ceux avec lesquels je travaille; -).)

Quand j'écrivais langage assembleur il était logique de pinailler sur des octets et des cycles, mais qui était il y a longtemps et compilateurs ont parcouru un long chemin depuis. Je ne voudrais pas essayer de manuellement-optimize un maintenant.

De même, quand je suis passé à écrire en C, il était assez facile de faire un meilleur travail que les compilateurs C, mais chaque année Borland ou Microsoft ou quelqu'un libérerait un nouveau « n amélioré qui a lancé le précédent autour de la salle . J'ai commencé à prêter attention au code assembleur réel que le compilateur émettait et, danged si elle n'a pas été en train d'écrire quelques belles et le code serré, le déroulement des boucles, des variables en mouvement en dehors des boucles, etc.

jours Maintenant, je suis dans l'écriture beaucoup plus élevées langues comme Perl, Python et Ruby. J'utilise quelques-uns des trucs du compilateur avant, comme la boucle si elle fait dérouler le sens, le déplacement des variables statiques en dehors des boucles, etc., mais je ne vous inquiétez pas à ce sujet presque autant que les processeurs sont un peu plus vite weeeeee maintenant. Si une application semble glisser de façon inattendue alors je vais utiliser un profileur et voir ce que je peux trouver, et si quelque chose peut être amélioré, je vais commencer l'analyse comparative de diverses façons que je peux penser à faire quelque chose plus vite, puis voir comment il échelles vers le haut.

En général, j'essaie d'être intelligent sur la façon dont j'écrire du code, basé sur des années d'expérience.

Un micro-optimisation: amélioration de la performance monothread des choses qui sont parallélisables ou qui peuvent simplement être améliorés avec un nouveau matériel.

Si quelque chose est lent sur un ordinateur il y a de 10 ans, une solution moins coûteuse est sans doute d'acheter une version plus récente, ordinateur plus rapide, plutôt que de perdre du temps de l'optimisation programmeur. Une grande mise au point d'optimisations considérées, cependant, devrait être de trouver un moyen d'utiliser les 8 cœurs que vous pouvez obtenir aujourd'hui, ou 64, vous serez en mesure d'obtenir dans quelques années, au lieu de se éterniser sur les minuties comme le coût supplémentaire des ordures collection.

Micro-optimisation en termes de performance d'exécution est à peine un problème fermé aujourd'hui encore (bien qu'il pourrait être moins fréquent). J'ai de temps en temps à expliquer aux gens que les frais généraux d'attribution d'un objet supplémentaire à chaque demande ou l'ajout d'un appel de fonction supplémentaire est négligeable.

En dehors de cela, je vois aussi les programmeurs micro-optimize pour la simplicité (y compris moi-même). Je dois encore travailler quelque part que je ne devais pas expliquer la différence entre la simplicité et simplisme.

Je suis pour le ne-optimize, à moins-vraiment-nécessaire principe. Et je suis pour le principe de profil-première. Et en principe, je ne quelque chose qui optimize fera une différence nécessaire.

C'est en principe. Mais le principe est un menteur.

J'ai l'habitude de prendre soin des fonctions dans les bibliothèques fréquemment utilisées que je pense que ce sera beaucoup utilisé dans les boucles internes. Et puis, quand vous apercevez quelque chose dans une autre fonction, ce n'est pas si souvent utilisé ...

Oh - et puis il y a le « je l'écris - Bien sûr, il est une importante bibliothèque » logique

.

Oh - et BTW. Je ne l'ai jamais encore utilisé un profileur pour guider une optimisation. Ne pas avoir accès à un commercial, et jamais tout à fait construit la motivation pour comprendre gprof.

En fait, je suis un hypocrite. Ces principes sont applicables à d'autres personnes, mais j'ai trop peur de quelqu'un dire « mais pourquoi avez-vous écrit cette façon lente et merdique? » donc je ne pourrai jamais les appliquer vraiment bien pour moi.

Je ne suis pas aussi mauvais que je fais ici, cependant. Et je suis tout à fait à l'abri de l'auto-tromperie, vous savez que je ne me trompe pas à ce sujet!

EDIT

Je dois ajouter - un de mes grands décrochements stupides est les frais généraux d'appel. Pas partout, bien sûr, mais ceux que je-pense-être-physique, fera-USED-a-lot en interne boucles cas (où je n'ai aucune preuve objective d'un problème). J'ai écrit le code méchant basé offsetof à éviter de faire des appels de méthode virtuelle plus d'une fois. Le résultat peut même être plus lent, car il est sans doute pas un style de codage qui optimiseurs sont conçus pour traiter bien - mais il est intelligent ; -)

Dans l'ancien temps où les ordinateurs avaient des temps d'horloge mesurée en microsecondes, la mémoire en kilo-octets, et les compilateurs primitifs, micro-optimisation a un certain sens.

La vitesse et la taille des ordinateurs de la génération actuelle et la qualité des compilateurs de la génération actuelle signifie que les micro-optimisation est généralement une perte de temps. Les exceptions ont tendance à être quand vous devez absolument obtenir une performance maximum de un code ... ou de calculs que vous écrivez pour un système embarqué avec des ressources extrêmement limitées.

mais je suis à la recherche de ce que les programmeurs faire perdre du temps, de ne pas optimiser les performances d'exécution.

Twitter et Facebook viennent à l'esprit: -)

Licencié sous: CC-BY-SA avec attribution
scroll top