Si vous voyez un article indiquant que la langue X est plus rapide que la langue Y, vous pouvez fermer l'article.





Avec mon cerveau humanitaire, j'ai toujours pensé de cette façon - si un programmeur sait comment le rendre plus performant, alors il doit être plus performant. Une solution productive = la bonne solution. Un langage de programmation peut être plus lent qu'un autre, et s'il s'avère, le langage de programmation est gaspillé.



Eh bien, bien sûr - si le développeur est un spécialiste de la performance, il se noiera pour toutes ces choses, même si elles sont fausses.



Naturellement, tout cela n'a pas de sens, mais ce n'est pas à moi de vous en parler. Par conséquent, Andrei Akinshin, un développeur et mathématicien, candidat en sciences physiques et mathématiques, mainteneur de BenchmarkDotNet et perfolizer, auteur du livre Pro .NET Benchmarking et juste un ingénieur très, très cool, est venu à notre podcast.





Vous trouverez ci-dessous des citations sélectionnées.



Il est impossible de tout prévoir dans les benchmarks



Un de mes collègues a récemment eu ce qui suit. Il avait programmé le matin, tout allait bien pour lui, tout fonctionnait rapidement. À un moment donné, tout a commencé à coller - Rider est lent, IDEA, le navigateur - tout est lent. Il ne pouvait en aucun cas comprendre quel était le problème? Et puis j'ai réalisé. Il a travaillé sur un ordinateur portable noir qui se tenait près de la fenêtre. Il faisait assez frais le matin et le soleil se levait pendant la journée, l'ordinateur portable est devenu très chaud et est entré en régulation thermique.



Il sait qu'il existe une telle chose, sait que l'environnement physique peut affecter la performance et il a rapidement réalisé ce qui se passait. Il avait en tête un modèle selon lequel le monde fonctionne, et dans ce modèle il a plus ou moins vite compris ce qui se passait.



Autrement dit, la compétence la plus importante qui peut être obtenue dans l'analyse comparative est de ne pas tout savoir dans tous les détails - tous les temps d'exécution et tout le matériel. L'essentiel est de comprendre comment vous devez agir pour trouver le problème, de préférence le plus rapidement possible avec un minimum d'effort.



Je vais faire une analogie avec les langues. Lorsque vous apprenez votre premier langage de programmation fonctionnel, vous devez légèrement modifier votre attitude face au monde - pour comprendre les principes de la programmation fonctionnelle, comment vous devez généralement penser. Ensuite, vous prenez le prochain langage fonctionnel X, et vous avez déjà ces principes en tête. Vous regardez un couple hello world et commencez à écrire aussi.



Dans le même temps, vous ne connaissez peut-être pas certaines des nuances de la langue. Vous ne savez peut-être pas comment fonctionnent certaines constructions syntaxiques, mais cela ne vous dérange pas beaucoup. Vous vous sentez à l'aise et écrivez. J'ai été confronté à un comportement incompréhensible - j'ai lu le manuel, je l'ai compris, un fait nouveau est facilement entré dans votre image du monde, et vous êtes allé plus loin. Et vous n'apprendrez jamais toutes les nuances de tous les langages fonctionnels du monde, mais l'approche générale restera dans votre tête.



Je pense que vous devez atteindre un niveau similaire dans chaque domaine, puis aller plus loin.



À un moment donné de l'analyse comparative, je me suis concentré spécifiquement sur la précision des mesures, sur les caractéristiques de certains temps d'exécution, un morceau de fer, autre chose. Ensuite, j'ai arrêté de découvrir l'Amérique à chaque fois, et tous les problèmes de performances ont commencé à tomber dans les classes que je connaissais déjà. Et je suis allé en profondeur - dans le sens de l'analyse des performances: que faire des chiffres que nous avons mesurés. Et c'est dans ce domaine que je n'ai pas encore atteint le bord de la connaissance. Certaines choses sont déjà devenues claires pour moi, mais il reste encore beaucoup à faire: comprendre comment appliquer tout cela dans la pratique, quelles formules utiliser, lesquelles ne pas utiliser, quelles approches sont bonnes, lesquelles ne le sont pas.



L'analyse comparative au nom de l'analyse comparative n'est pas la meilleure chose à faire



Il devrait toujours y avoir des exigences de performance commerciale, vous devez toujours comprendre ce que vous recherchez. Si vous n'avez pas d'exigences commerciales, il est inutile non plus de faire de la performance. En conséquence, quand il y a des besoins commerciaux, vous commencez déjà à comprendre quelles approches, au moins à l'œil nu, vous pouvez utiliser et lesquelles ne le peuvent pas. Dans le cas contraire, allez-y, comparez, vérifiez - quelles approches correspondent à vos besoins.



Et lorsque vous disposez d'un ensemble d'algorithmes, d'options pour écrire du code, de la conception et d'autres choses, et que tout correspond aux exigences, vous choisissez déjà ce qui sera le plus cohérent avec le reste du projet, qui reflète votre point de vue sur l'esthétique, sur la façon d'écrire correctement le code ...



En gros, si j'ai un maximum de 10 éléments dans une collection, et qu'il y a deux options - écrire un algorithme simple pour un cube ou un algorithme très complexe pour n * log n - j'en écrirai un simple pour un cube qui sera clair pour tout le monde, qui sera facile à maintenir et à modifier. Parce que je comprends qu'il ne franchira jamais mes limites de performance.



Si vous avez écrit une solution lente pour un petit ensemble de données, puis que vous l'avez utilisée pour un grand ensemble de données, et que cela n'a pas eu de très mauvaises conséquences (généralement aucune) - eh bien, allons-y et corrigeons-le. Mais dans ma tête, il y aura un modèle pour éviter ces erreurs à l'avenir.



Par exemple, vous pouvez mettre une assertion au tout début de la méthode afin que le nombre d'éléments de la collection ne dépasse pas tel ou tel nombre. Ensuite, le prochain programmeur qui essaiera accidentellement d'utiliser votre méthode verra immédiatement une exception et ne l'utilisera pas. De telles choses viennent avec l'expérience.



Il y a un autre problème: les exigences commerciales volatiles. Ils vont certainement changer - c'est un axiome de notre réalité, il n'y a aucun moyen de s'en éloigner. Avec l'expérience, vous serez en mesure de prédire à l'œil nu où les exigences peuvent changer, où il vaut la peine de fixer un bon niveau de performance, où la charge peut augmenter.



Bien que cette intuition ne soit pas là, vous pouvez faire des essais et des erreurs et voir ce qui se passe.



Vous avez toujours un compromis entre performance et beauté



Si vous écrivez aussi efficacement que possible, très probablement, votre code sera tout simplement terrible, dégoûtant - et même si vous fermez les yeux sur l'esthétique, il sera difficile à maintenir, des bugs subtils y apparaîtront constamment, car l'architecture est mauvaise, le code est mauvais, tout va mal.



Je pense que vous devez vous concentrer sur les exigences commerciales actuelles et écrire le code le plus propre, le plus compréhensible, le plus beau et le plus maintenable. Et au moment où il commence à appuyer (ou on a le sentiment que cela va bientôt commencer), alors quelque chose a déjà changé.



Et même si vous vous concentrez toujours uniquement sur les performances, il n'existe pas de code parfaitement optimisé et productif au maximum. Cela signifie tout - oublié C #, oublié tous les beaux langages. Et il vaut mieux écrire en général en codes machine, car l'assembleur est également limité en syntaxe. Et si vous écrivez immédiatement sur les octets, vous obtiendrez une amélioration des performances.



Dans certains cas, le code le plus rapide s'avère être le plus beau, le plus évident, le plus correct. Mais de tels compromis surviennent inévitablement dans des dizaines et des centaines de petits moments. Disons qu'il existe une chose telle que la vérification d'une violation des limites du tableau. Vous pouvez convenir que le runtime prendra soin de vous pour vérifier les limites du tableau à tous les endroits, et si vous vous tournez vers le premier élément moins, vous obtiendrez une exception et vous ne lirez pas à partir du bloc de mémoire gauche.



Et pour cette confiance que vous ne soustrayez jamais du mauvais morceau de mémoire - vous payez avec un petit morceau de performance. Autrement dit, nous utilisons la performance comme une ressource afin de rendre le programme plus stable, compréhensible et maintenable.



La langue n'a pas de propriété telle que la performance



Si vous voyez un article indiquant que X est plus rapide que Y, vous pouvez fermer l'article. La langue est une abstraction mathématique. Il s'agit d'un ensemble de règles selon lesquelles le programme est compilé. Il n'a pas de performance, il n'a pas de performance, c'est quelque chose qui existe dans votre tête et qui s'incarne dans un éditeur de texte.



Les performances sont disponibles pour des environnements d'exécution, des environnements, des programmes spécifiques, des apishe spécifiques. Lorsque vous prenez en compte tous ces facteurs, vous pouvez parler de performance. Mais il y a une explosion combinatoire, et vous ne pouvez pas dire qu'un code dans ce langage est toujours plus rapide qu'un autre code dans celui-ci, car de nouvelles versions de matériel et de runtimes sortent. Vous ne passerez jamais par toutes les combinaisons possibles de facteurs externes dans votre vie. Les apish que vous utilisez sont fondamentalement différents.



Par exemple, dans un langage conditionnel aux premiers stades de développement, ils ont implémenté une méthode de tri à l'aide d'une bulle. Eh bien, je ne sais pas - les gars voulaient déployer la version dès que possible, ont écrit le tri le plus simple qu'ils pouvaient faire. Vous l'avez pris, utilisé cette méthode, et il s'est avéré être plus lent sur le Big Data que dans une autre langue où le tri rapide est effectué. Cela signifie-t-il que vous pouvez parler des performances de certaines langues? Non. Vous pouvez dire que cet apish particulier de cette langue sur ce système d'exploitation, sur ce matériel, dans ces environnements, fonctionne plus lentement qu'un autre apish d'une autre langue dans un autre environnement. Alors vous pouvez dire. Mais ce sera un très long paragraphe de texte à formuler correctement.



Par convention, on peut dire que C ++ est dans la plupart des cas plus rapide que JavaScript. Mais il serait plus correct de dire que les programmeurs C ++ ayant une bonne expérience C ++ qui écrivent en C ++ écriront un programme qui est susceptible d'être plus rapide qu'un javascript JavaScript ou écriront quelque chose qui fonctionnera dans un navigateur.



Mais il y a aussi de nombreuses réserves ici. Mais que se passe-t-il si un mec qui a écrit en JavaScript dit que ce n'est pas le cas, et y va vers une sorte de WebAssembly ou quelque chose d'autre à refaire. Ou trouvez sur GitHub un superinterpréteur / compilateur JavaScript qui fonctionne avec un sous-ensemble très tronqué de JS par trois constructions syntaxiques et demie, mais produit un code natif ultra-rapide.



Et là, si vous le souhaitez, vous pouvez écrire un code qui dépassera le C ++. De plus, vous pouvez écrire votre propre compilateur JavaScript, qui sera conçu pour compiler un seul programme et dépasser les «plus» en termes de vitesse. Et c'est, en principe, une option valable.



Pression sociale d'un projet open source populaire



La croissance et la popularité des projets s'accompagnent d'un certain niveau de responsabilité. Mais vous n'avez pas vraiment d'obligations. Ce fait n'est pas toujours facile à comprendre, surtout quand toutes sortes de gens viennent sur GitHub et disent: «Cela ne fonctionne pas pour moi ici! Réparez-le de toute urgence! J'ai vraiment besoin de ça pour fonctionner. Allez le réparer! " Ou un mec trouve un travail et je suis en vacances. Trois ou quatre jours passent, je n'ai même pas vu qu'il avait commencé quelque chose là-bas. Je me repose quelque part, et le mec commence - «Pourquoi diable ne me réponds-tu pas? Quel genre de communauté ce projet a-t-il?! Vous êtes généralement tous des gens dégoûtants, vous devez faire de mauvaises choses avec vous! J'ai perdu mon temps, je t'ai écrit que tu as tort, et que tu ne fais rien du tout, tu m'ignores depuis quatre jours! Comment est-ce possible ?! "



Et plus le projet est populaire, plus la pression sociale des personnes qui croient que l'open source est un endroit où d'autres personnes font votre travail gratuitement est forte. Mais en fait ce n'est pas le cas.



Et maintenant, lorsque l'immunité apparaît contre les personnes qui veulent quelque chose de vous, la vie devient beaucoup plus facile. Maintenant, j'arrive à BenchmarkDorNet lorsque j'ai le temps et l'humeur de coder. Je sais qu'il y a beaucoup de bugs là-bas. Ils ne sont pour la plupart pas critiques, et concernent une sorte de cas marginaux - dans tel ou tel environnement avec le dernier aperçu du cinquième DotNet, quelque chose ne fonctionne pas quelque part. Eh bien, d'accord, que ça ne marche pas. Quand je suis d'humeur, je vais y remédier.



Si d'autres personnes en ont besoin, ils peuvent le réparer eux-mêmes et envoyer une demande de tirage - je ferai un examen lorsque j'aurai le temps et l'humeur.






Regardez le podcast en entier ici .



All Articles