Qu'est-ce qui détermine la «vitesse» d'un langage de programmation?

38

Supposons qu’un programme soit écrit en deux langues distinctes, qu’il s’agisse de la langue X et de la langue Y, si leurs compilateurs génèrent le même code octet, pourquoi devrais-je utiliser la langue X au lieu de la langue Y? Qu'est-ce qui définit qu'une langue est plus rapide qu'une autre?

Je vous pose cette question car vous voyez souvent des gens dire des choses telles que: "C est la langue la plus rapide, ATS est une langue rapide comme C". Je cherchais à comprendre la définition de "rapide" pour les langages de programmation.

Rodrigo Valente
la source
21
Si un programme est plus rapide qu'un autre, cela signifie qu'il ne peut pas avoir le même code octet.
svick
5
Les langues ne sont qu'une notion utilisée pour écrire des programmes. Vous ne pouvez donc pas vraiment parler de la vitesse d'une langue.
Juho
1
@ Raphaël Je pense que c'est hors sujet, peu clair et beaucoup trop large. Bien que le sujet soit mieux adapté au génie logiciel , j’imagine qu’il serait fermé car trop large.
David Richerby
2
Mise à part l'implémentation, "rapidité" est ambigu, il existe différentes vitesses pour implémenter, compiler, exécuter et déboguer, et vous allez généralement en échanger certaines contre d'autres (sinon nous utiliserions tous le langage de programmation)
Nick T
Comme ci-dessus. Les langues ne génèrent pas le même code octet. Certaines langues sont plus faciles à analyser en code octet. Certains ont un niveau d'abstraction plus élevé.
superluminaire

Réponses:

23

Plusieurs raisons peuvent être envisagées pour choisir un langage X plutôt qu'un langage Y. La lisibilité du programme, la facilité de programmation, la portabilité sur de nombreuses plates-formes, l'existence de bons environnements de programmation peuvent être de telles raisons. Cependant, je n’examinerai que la rapidité d’exécution demandée dans la question. La question ne semble pas prendre en compte, par exemple, la vitesse de développement.

Deux langues peuvent être compilées sous le même code octet, mais cela ne signifie pas que le même code sera produit.

En fait, le bytecode est uniquement du code pour une machine virtuelle spécifique. Il présente des avantages techniques, mais n'introduit pas de différences fondamentales avec la compilation directe pour un harware spécifique. Donc, vous pourriez aussi bien envisager de comparer deux langages compilés pour une exécution directe sur le même ordinateur.

Cela dit, la question de la vitesse relative des langues est ancienne et remonte aux premiers compilateurs.

Pendant de nombreuses années, à cette époque, Professional considérait que le code écrit à la main était plus rapide que le code compilé. En d'autres termes, le langage machine était considéré comme plus rapide que les langages de haut niveau tels que Cobol ou Fortran. Et c'était à la fois plus rapide et généralement plus petit. Les langages de haut niveau sont encore développés car ils étaient beaucoup plus faciles à utiliser pour de nombreuses personnes qui n'étaient pas des informaticiens. Le coût d'utilisation de langages de haut niveau porte même un nom: le taux d'expansion, qui peut concerner la taille du code généré (un problème très important à cette époque) ou le nombre d'instructions réellement exécutées. Le concept était principalement expérimental, mais le ratio était supérieur à 1 au début, car les compilateurs effectuaient un travail assez simple selon les normes actuelles.

Ainsi, le langage machine était plus rapide que Fortran.

Bien sûr, cela a changé au fil des ans, à mesure que les compilateurs sont devenus plus sophistiqués, au point que la programmation en langage assembleur est maintenant très rare. Pour la plupart des applications, les programmes en langage assembleur sont en concurrence médiocre avec le code généré par l'optimisation des compilateurs.

Cela montre que l'un des problèmes majeurs est la qualité des compilateurs disponibles pour le langage considéré, leur capacité à analyser le code source et à l'optimiser en conséquence.

Cette capacité peut dépendre, dans une certaine mesure, des caractéristiques du langage pour souligner les propriétés structurelles et mathématiques de la source afin de faciliter le travail du compilateur. Par exemple, un langage pourrait permettre l'inclusion d'énoncés concernant les propriétés algébriques des fonctions définies par l'utilisateur, de manière à permettre au compilateur d'utiliser ces propriétés à des fins d'optimisation.

Le processus de compilation peut être plus facile, produisant ainsi un meilleur code, lorsque le paradigme de programmation du langage est plus proche des fonctionnalités des machines qui interprèteront le code, qu’il soit réel ou virtuel.

Un autre point est de savoir si les paradigmes mis en œuvre dans le langage sont fermés au type de problème programmé. Il faut s’attendre à ce qu’un langage de programmation spécialisé dans des paradigmes de programmation spécifiques compile très efficacement les fonctionnalités liées à ce paradigme. Par conséquent, le choix d'un langage de programmation peut dépendre, pour des raisons de clarté et de rapidité, du choix d'un langage de programmation adapté au type de problème à programmer.

La popularité du C pour la programmation système est probablement due au fait que ce dernier est proche de l’architecture de la machine et que la programmation système est également directement liée à cette architecture.

Un autre problème sera plus facilement programmé, avec une exécution plus rapide utilisant la programmation logique et les langages de résolution de contraintes .

Les systèmes réactifs complexes peuvent être programmés de manière très efficace avec des langages de programmation synchrones spécialisés comme Esterel, qui incorpore des connaissances très spécialisées sur de tels systèmes et génère un code très rapide.

Pour prendre un exemple extrême, certains langages sont hautement spécialisés, tels que les langages de description de syntaxe utilisés pour programmer des analyseurs. Un générateur d'analyseur n'est qu'un compilateur pour de tels langages. Bien sûr, il n’est pas encore complet, mais ces compilateurs sont extrêmement bons pour leur spécialité: produire des programmes d’analyse syntaxique efficaces. Le domaine de la connaissance étant restreint, les techniques d'optimisation peuvent être très spécialisées et réglées très finement. Ces générateurs d’analyseurs sont généralement bien meilleurs que ce qui pourrait être obtenu en écrivant du code dans une autre langue. Il existe de nombreux langages hautement spécialisés avec des compilateurs qui produisent un code excellent et rapide pour une classe restreinte de problèmes.

Par conséquent, lors de l'écriture d'un grand système, il peut être judicieux de ne pas compter sur une seule langue, mais de choisir la meilleure langue pour différents composants du système. Ceci pose bien entendu des problèmes de compatibilité.

Un autre point qui compte souvent est simplement l’existence de bibliothèques efficaces pour les sujets programmés.

Enfin, la vitesse n'est pas le seul critère et peut être en conflit avec d'autres critères tels que la sécurité du code (par exemple en ce qui concerne les mauvaises entrées, ou la résilience face aux erreurs système), l'utilisation de la mémoire, la facilité de programmation (bien que la compatibilité des paradigmes puisse réellement aider cela). ), taille du code objet, maintenabilité du programme, etc.

La vitesse n'est pas toujours le paramètre le plus important. En outre, cela peut prendre différentes formes, telles que la complexité, qui peut être une complexité moyenne ou une complexité pire. En outre, dans un grand système comme dans un programme plus petit, il existe des domaines dans lesquels la rapidité est essentielle, et d'autres dans lesquels cela importe peu. Et ce n’est pas toujours facile de déterminer cela à l’avance.

babou
la source
Merci. C'est quelque chose comme ça. Je cherchais. Il était difficile de trouver de la matière pour le sujet. Ceci clarifié assez.
Rodrigo Valente
@ RodrigoAraújoValente Merci, vous voudrez peut-être examiner cette question . Selon un point de vue extrémiste, un compilateur pour le langage L peut simplement associer un interpréteur pour L avec le code source du programme, sans rien faire. Vous pouvez ensuite faire mieux en essayant d’optimiser le calcul du paquet (évaluation partielle). Plus vous optimisez et plus votre langue sera rapide. La question est alors: qu'est-ce qui peut vous aider à optimiser? Les réponses peuvent inclure une bonne connaissance du sujet spécialisé, l'aide d'un programmeur, des analyses sophistiquées, etc.
babou
Par "même bytecode", je suppose que vous entendez "le même genre de représentation exécutable". Il est évident que des exécutables identiques fonctionneront à la même vitesse (en supposant le même système d’exécution). (J'aurais probablement examiné cela du point de vue de l'information / de la communication. En théorie , un programmeur peut tout savoir sur le programme et le matériel alors qu'un langage restreint souvent la communication (limitant les transformations autorisées ou utiles) et que le compilateur ignore peut-être Détails microarchitecturaux. La compilation et le développement du compilateur sont essentiels au développement et à la ...
Paul A. Clayton
Cela entre ensuite dans quoi les humains sont généralement bons (par exemple, en reconnaissant les modèles généraux) par rapport à ce que les ordinateurs sont généralement bons dans (par exemple, la tenue de registres et "l'arithmétique"). De plus, la communication des informations d’exécution est souvent plus conviviale (l’optimisation guidée par le profil peut pallier un certain manque d’informations communiquées via le langage de programmation). L'optimisation dynamique ne serait pas pratique pour les programmeurs humains ...
Paul A. Clayton
(Bien que l'on puisse dire la même chose de l'écriture de tous les logiciels en assemblage par des programmeurs expérimentés ciblant un matériel spécifique, au moment de l'optimisation du logiciel, non seulement le matériel aurait changé, mais le logiciel serait obsolète).)
Paul A. Clayton
16

Bien que tout soit finalement exécuté sur le processeur * , il existe diverses différences entre les différentes langues. Voici quelques exemples.

Langages interprétés Certains langages sont interprétés plutôt que compilés , par exemple Python, Ruby et Matlab. Cela signifie que le code Python et Ruby ne se compile pas en code machine, mais est plutôt interprété à la volée. Il est possible de compiler Python et Ruby sur une machine virtuelle (voir point suivant). Voir aussi cette question . L'interprétation est généralement plus lente que le code compilé pour diverses raisons. L'interprétation elle-même peut non seulement être lente, mais il est également plus difficile de faire des optimisations. Cependant, si votre code passe le plus clair de votre temps sur les fonctions de bibliothèque (cas de Matlab), les performances n'en pâtiront pas.

Machine virtuelle Certains langages sont compilés en bytecode , un "code machine" inventé qui est ensuite interprété. Les exemples par excellence sont Java et C #. Bien que le bytecode puisse être converti en code machine à la volée, le code fonctionnera probablement encore plus lentement. Dans le cas de Java, une machine virtuelle est utilisée pour la portabilité. Dans le cas de C #, il peut y avoir d'autres problèmes tels que la sécurité.

Frais généraux Certaines langues négocient efficacité et sécurité. Par exemple, certaines versions de Pascal vérifieraient que vous n’accédez pas à un tableau en dehors des limites. Le code C # est "géré", et cela a un coût. Le garbage collection est un autre exemple courant. Il permet au programmeur de gagner du temps, mais n'est pas aussi efficace que la gestion de la mémoire. Il existe d'autres sources de charge, telles que l'infrastructure pour la gestion des exceptions ou la prise en charge de la programmation orientée objet.

* En fait, les systèmes hautes performances de nos jours exécutent également le code sur les GPU et même sur les FPGA.

Yuval Filmus
la source
Donc, fondamentalement, si j'ai besoin de plus de performances, je devrais choisir des langages compilés? Et à propos des paradigmes? Il y a une raison de choisir fonctionnel au lieu de oop, ou vice versa?
Rodrigo Valente
Votre remarque sur la récupération de place est un peu simpliste. Il n'est pas toujours décidable statiquement lorsque la mémoire allouée n'est plus utilisée. Même décisif, il peut être très difficile de déterminer sans commettre d'erreur. De ce fait, la GC est parfois nécessaire et souvent plus sûre (comme les limites de checkarray). De plus, il peut être combiné avec une libération explicite.
Babou
@ RodrigoAraújoValente Depends. Le code de merde compilera souvent en code de merde. Peut-être que le code que vous pouvez écrire en Python est en réalité plus rapide que le code que vous pouvez écrire en C.
Raphael
nit: comme expliqué par la question à laquelle vous avez lié, python n'est pas interprété "à la volée" :)
Eevee
Aucune des langues que vous mentionnez dans la section interprétée n'est interprétée à la volée. Python est compilé en bytecode, Ruby a été compilé pour AST, mais je crois qu’il est maintenant compilé en bytecode. Matlab, je crois, est maintenant en fait compilé JIT. En fait, je ne connais aucune implémentation en langage non-niche interprétant les choses à la volée plutôt que compilant au moins une sorte de représentation de machine virtuelle.
Winston Ewert
5

Il y a différents facteurs pour choisir X au lieu de Y, comme

  • Facilité d'apprentissage
  • Facilité de compréhension
  • Vitesse de développement
  • Aide à l'application du code correct
  • Performance du code compilé
  • Environnements de plateforme pris en charge
  • Portabilité
  • Adaptée à l'objectif

Certains langages conviennent au développement de projets d’entreprise tels que C # ou Python, mais d’autre part, d’autres sont utiles pour la programmation système telle que C ++.

Vous devez déterminer sur quelle plate-forme vous allez travailler et quelle application vous allez créer.

M ama D
la source
1
Alors, comment puis-je déterminer les performances du code compilé? C'est essentiellement ce qui m'a fait faire cette question.
Rodrigo Valente
6
Cette réponse est certes un bon conseil, mais je ne vois pas comment cela répond à la question, qui concerne la vitesse en tant que facteur de choix pour une langue.
Babou
@ RodrigoAraújoValente Ils ne peuvent même pas être du code compilé (si votre langue est interprétée).
Raphaël
1
Vous voudrez peut-être ajouter "Bonnes bibliothèques" et "Bons outils".
Raphaël
@ RodrigoAraújoValente Vous l'exécutez et le profilez.
Kyle
2

Le langage de programmation "le plus rapide" que vous pouvez obtenir avec n'importe quelle plate-forme est le langage d'assemblage du chipset auquel vous faites face. A ce niveau, il n'y a pas de traduction. Cependant, il est nécessaire de savoir comment le chipset exécute les instructions, en particulier celles capables de fonctionner en parallèle.

La conversion de C en assemblage est très "superficielle": elle est proche de un à un mais elle est plus lisible. Cependant, il a beaucoup de couches au-dessus en raison des bibliothèques standard pour améliorer la portabilité. Le compilateur aurait besoin de moins de choses pour obtenir le code assembleur et les optimisations les plus puissantes permettent généralement d’apporter des modifications spécifiques à la machine.

C ++ ajoute un langage plus riche. Cependant, étant donné que le langage ajoute tellement de complexité, il devient plus difficile au compilateur de créer un code optimal pour la plate-forme.

Ensuite, nous passons de l’autre côté de l’échelle. Langues interprétées Celles-ci tendent à être les plus lentes car outre le travail, il faut un peu de temps pour analyser le code et le convertir en appels machine.

Ensuite, nous avons ceux entre les deux. Généralement, ils ont une couche de machine virtuelle optimisée pour la plate-forme. Et le compilateur va créer du code pour que la machine virtuelle s'exécute. Parfois, cela se produit tout à la fois comme Perl, Pascal, Ruby ou Python. Ou en plusieurs étapes comme java.

Certaines de ces machines virtuelles ajoutent la notion de compilateur JIT qui accélère également l'exécution en créant un code au niveau de la machine plutôt qu'en traduisant le code d'octet intermédiaire.

Certaines machines virtuelles sont de bas niveau, ce qui permet moins de traduction du code octet en code machine. Ce qui accélère les choses tout en gardant la portabilité.

Archimedes Trajano
la source
Historiquement, C a été conçu pour permettre une traduction facile en code machine. Cependant, de plus en plus, pour convertir le code C en code C efficace, un compilateur doit comprendre ce qu’un programmeur essayait de faire puis traduire cette intention en code machine. Par exemple, historiquement, l'équivalent de code machine de *p++=*q++;sur de nombreuses machines a été plus rapide que array1[i]=array2[i];sur de nombreux processeurs, l'inverse est souvent vrai, de sorte que les compilateurs peuvent finir par convertir le style précédent en code - ce n'est guère une conversion "superficielle".
Supercat
C'est généralement si vous le faites, -O0il ne fera aucune optimisation. Les optimisations sont un bonus que vous obtenez avec le compilateur, mais le langage en lui-même peut se traduire de manière quasi directe en assembleur.
Archimedes Trajano
2

Un point qui n’a pas encore été mentionné est que dans certaines langues, exécuter le même morceau de code plusieurs fois exécutera toujours la même séquence d’actions; il suffit donc à l’ordinateur de déterminer une fois ce que la section de code doit faire. L'un des principaux avantages du dialecte JavaScript "strict" consiste en ce qu'une fois que le moteur JavaScript détermine le fonctionnement d'un morceau de code, il peut utiliser ces informations lors de sa prochaine exécution. sans "utiliser strict", il ne peut pas.

Par exemple, en l'absence de "use strict", un morceau de code comme:

function f() { return x; }

peut renvoyer une variable X dans le contexte d’appel immédiat, s’il en existe une, ou une variable X à partir d’un contexte d’appel externe, ou peut renvoyer Undefined. Pire, en boucle comme:

for (i=0; i<40; i+=1) { g(i); }

le moteur JavaScript n'a aucun moyen de savoir ce qui g()pourrait faire avec i[ou pour glui-même d'ailleurs. Depuis gou ipeut légitimement changer ien une chaîne, le moteur JavaScript ne peut pas simplement utiliser une addition numérique et une comparaison numérique dans la boucle, mais doit à chaque passage dans la boucle vérifier si l'un des appels de fonction a effectué quoi que ce soit iou g. En revanche, dans le dialecte "use strict" [un peu sain], le moteur JavaScipt peut examiner le code ci-dessus et savoir que chaque passage de la boucle utilise la même variable numérique et appelle la même fonction. Il suffira donc d'identifier iet de fonctionnerg une fois, plutôt que de devoir les regarder à chaque passage dans la boucle - un gain de temps considérable.

supercat
la source
2

Eh bien, il existe des réponses assez professionnelles ici, celle-ci n’en est pas proche mais pourrait être intuitive pour vous.

Vous avez peut-être souvent entendu dire que lorsque vous avez besoin d'exécuter une tâche aussi rapidement que possible, vous souhaitez écrire le code qui l'exécute en assembleur. En effet, vous n'exécutez que les commandes dont vous avez réellement besoin pour terminer la tâche, et rien de plus. Si vous utilisez un langage de haut niveau, vous pouvez implémenter cette tâche sur plusieurs lignes, mais le compilateur doit toujours les traduire en langage machine. Cette traduction n'est pas toujours minimaliste car vous pourriez l'écrire directement. Cela signifie que la machine passera de nombreuses horloges à exécuter des commandes que vous pourriez épargner.

Bien que les compilateurs soient très sophistiqués, ils ne sont toujours pas aussi efficaces que les meilleurs programmeurs d’assemblage.

Poursuivant dans cette direction, le nombre de commandes inutiles augmente (généralement) à mesure que le langage est de niveau supérieur. (ce n'est pas vrai à 100% pour toutes les langues de haut niveau)

Donc, pour moi, la langue X est plus rapide que la langue Y (au moment de l'exécution) si, pour certains morceaux de code, le code machine de X est plus court que Y.

johni
la source
L'assemblée est complètement défoncée. Cependant, il faut un vrai artiste pour surpasser les meilleurs compilateurs.
Johan - rétablir Monica
1

Il est difficile de répondre définitivement à cette question car elle est si complexe et multidimensionnelle (c'est presque comme par exemple comparer des marques de voitures sur plusieurs critères), mais il existe de nouvelles études scientifiques comprenant un excellent référentiel de code connu sous le nom de code Rosetta ( aperçu de wikipedia ). Cette enquête 2014 par Nanz et Furia étudie cette question de manière tout à fait définitive et scientifique sur la base des critères typiques suivants et d’une analyse quantitative rare de qualités de code typiquement subjectives. L'abrégé contient des constatations et des généralisations fondées objectivement. (J'espère que d'autres études s'appuyant sur ces résultats pourront être réalisées à l'avenir.)

  • RQ1. Quels langages de programmation permettent un code plus concis?

  • RQ2. Quels langages de programmation compiler dans des exécutables plus petits?

  • RQ3. Quels langages de programmation ont de meilleures performances en temps d'exécution?

  • RQ4. Quels langages de programmation utilisent la mémoire plus efficacement?

  • RQ5. Quels langages de programmation sont moins sujets aux erreurs?

Résumé - Parfois, les débats sur les langages de programmation sont plus religieux que scientifiques. Les questions concernant le langage le plus succinct ou le plus efficace, ou améliorant la productivité des développeurs, sont discutées avec ferveur et leurs réponses sont trop souvent basées sur des anecdotes et des croyances infondées. Dans cette étude, nous utilisons le potentiel de recherche largement inexploité de Rosetta Code, un référentiel de code de solutions aux tâches de programmation courantes dans différentes langues, qui offre un grand ensemble de données à analyser. Notre étude est basée sur 7 087 programmes de solution correspondant à 745 tâches dans 8 langages largement utilisés représentant les principaux paradigmes de programmation (procédural: C et Go; orienté objet: C # et Java; fonctionnel: F # et Haskell; script: Python et Ruby). Notre analyse statistique révèle notamment que: les langages fonctionnels et de script sont plus concis que les langages procéduraux et orientés objet; C est difficile à battre quand il s’agit de la vitesse brute sur des entrées importantes, mais les différences de performance par rapport aux entrées de taille modérée sont moins prononcées et permettent même aux langages interprétés d’être compétitifs; les langages compilés fortement typés, où plus de défauts peuvent être détectés au moment de la compilation, sont moins sujets aux échecs d'exécution que les langages interprétés ou faiblement typés. Nous discutons des implications de ces résultats pour les développeurs, les concepteurs de langage et les éducateurs. où plus de défauts peuvent être détectés au moment de la compilation, sont moins sujets aux échecs d'exécution que les langages interprétés ou faiblement typés. Nous discutons des implications de ces résultats pour les développeurs, les concepteurs de langage et les éducateurs. où plus de défauts peuvent être détectés au moment de la compilation, sont moins sujets aux échecs d'exécution que les langages interprétés ou faiblement typés. Nous discutons des implications de ces résultats pour les développeurs, les concepteurs de langage et les éducateurs.

vzn
la source
0

Les langages informatiques ne sont qu'une abstraction de commandes pour expliquer à l'ordinateur ce qu'il doit faire.

Vous pouvez même écrire en langage informatique Pythonet le compiler avec un compilateur C (cython).

Garder cela à l'esprit, la vitesse des langages informatiques ne peut être comparée.

Mais vous pouvez comparer les compilateurs pour le même langage dans une certaine mesure. Par exemple GNU Ccompilateur contre Intel Ccompilateur. (Recherche du benchmark du compilateur)

Jonas Stein
la source
2
Si vous souhaitez faire des commentaires sur la question, veuillez utiliser la zone de commentaire, pas votre réponse. Notez qu’il s’agit de Computer Science Stack Exchange et que l’informatique n’est pas une programmation, de même que la littérature n’est pas un traitement de texte. Les questions relatives à la programmation sont diffusées en temps réel sur le logiciel ou le débordement de pile .
David Richerby