Maison  >  Article  >  Java  >  Pourquoi Java est-il plus rapide que Python ?

Pourquoi Java est-il plus rapide que Python ?

(*-*)浩
(*-*)浩original
2019-05-16 09:30:155033parcourir

Python est lent, voici les raisons courantes : "Parce que c'est un GIL (Global Interpreter Lock)", "Parce que c'est un langage interprété et non compilé", "Parce que c'est un langage typé dynamiquement".

Cours recommandés : Tutoriel Java.

Pourquoi Java est-il plus rapide que Python ?

Quelle raison a le plus grand impact sur les performances ?

« Parce que c'est le GIL »

Les processeurs des ordinateurs modernes ont plusieurs cœurs et parfois même plusieurs processeurs. Afin de tirer parti de toute la puissance de calcul, le système d'exploitation définit une structure sous-jacente appelée threads, et un processus (tel que le navigateur Chrome) peut générer plusieurs threads pour exécuter les instructions du système via des threads. De cette manière, si un processus utilise beaucoup de processeurs, la charge de calcul sera partagée entre plusieurs cœurs, permettant ainsi à la plupart des applications d'accomplir leurs tâches plus rapidement.

Au moment d'écrire ces lignes, mon navigateur Chrome a 44 fils de discussion ouverts. De plus, la structure des threads et l'API des systèmes d'exploitation basés sur POSIX (tels que Mac OS et Linux) sont différentes de celles des systèmes d'exploitation Windows. Le système d'exploitation est également responsable de la planification des threads.

Si vous n'avez pas écrit de programme multithread, vous devez comprendre le concept de verrous. Contrairement à un processus monothread, dans la programmation multithread, vous voulez vous assurer que lors de la modification de variables en mémoire, plusieurs threads n'essaient pas de modifier ou d'accéder à la même adresse mémoire en même temps.

CPython alloue de la mémoire lors de la création d'une variable puis utilise un compteur pour compter le nombre de références à la variable. Ce concept est appelé « comptage de références ». Si le nombre de références est 0, la variable peut être libérée du système. De cette façon, la création de variables « temporaires » (comme dans le contexte d’une boucle for) n’utilise pas la mémoire de votre application.

Le problème qui se pose est que si la variable est partagée entre plusieurs threads, CPython doit verrouiller le compteur de références. Il existe un « verrouillage global de l'interpréteur » qui contrôle soigneusement l'exécution des threads. Quel que soit le nombre de threads, l’interpréteur ne peut effectuer qu’une seule opération à la fois.

Quel impact cela a-t-il sur les performances des applications Python ?

Si l'application est à thread unique et à interprète unique, cela n'aura aucun impact sur la vitesse. La suppression du GIL n'affectera pas les performances du code.

Mais si vous souhaitez utiliser un interpréteur (un processus Python) pour obtenir la concurrence via des threads et que les threads sont gourmands en E/S (c'est-à-dire qu'il y a beaucoup d'entrées et de sorties réseau ou d'entrées et de sorties de disque ), alors ce qui suit se produira en compétition GIL :

Pourquoi Java est-il plus rapide que Python ?

Si une application Web (telle que Django) utilise WSGI, alors chaque requête envoyée à l'application Web sera exécuté par un interpréteur Python distinct, il n'y aura donc qu'un seul verrou par requête. Étant donné que l'interpréteur Python démarre très lentement, certaines implémentations WSGI prennent en charge le « mode démon » pour que le processus Python continue de fonctionner pendant une longue période.

« Parce que c'est un langage interprété »

J'ai beaucoup entendu cette raison, et je trouve qu'elle simplifie à l'extrême le fonctionnement réel de CPython. Lorsque vous écrivez python myscript.py dans le terminal, CPython lance une longue chaîne d'opérations, notamment la lecture, l'analyse lexicale, l'analyse syntaxique, la compilation, l'interprétation et l'exécution. Le point clé de ce processus est qu'il générera un fichier .pyc pendant la phase de compilation, et le bytecode sera écrit dans un fichier sous __pycache__/ (s'il s'agit de Python 3), ou écrit dans le même répertoire que le code source. (Python2). Cela est vrai non seulement pour les scripts que vous écrivez, mais également pour tout le code que vous importez, y compris les modules tiers.

Donc, dans la plupart des cas (sauf si vous écrivez du code qui ne s'exécutera qu'une seule fois), Python interprète le bytecode et l'exécute localement. Comparez cela à Java et C#.NET :

Java compile le code source dans un « langage intermédiaire », puis la machine virtuelle Java lit le bytecode et le compile à la volée en code machine. Il en va de même pour .NET CIL. Le Common Language Runtime (CLR) de .NET utilise la compilation juste à temps pour compiler le bytecode en code machine.

Alors, puisqu'ils utilisent tous deux une machine virtuelle et une sorte de bytecode, pourquoi Python est-il tellement plus lent que Java et C# dans les tests de performances ? La première raison est que .NET et Java sont compilés juste à temps (JIT).

JIT (Just-in-time) nécessite un langage intermédiaire pour diviser le code en petits morceaux (ou frames). Ahead of Time (AOT) signifie que le compilateur traduit le code source en code que le processeur peut comprendre avant de l'exécuter.

JIT lui-même ne rend pas l'exécution plus rapide car il exécute la même séquence de bytecode. Cependant, JIT peut effectuer des optimisations au moment de l'exécution. Un bon optimiseur GIT peut trouver les parties les plus exécutées de votre application, appelées « points chauds ». Ces bytecodes sont ensuite optimisés et remplacés par du code plus efficace.

Cela signifie que si votre application fait quelque chose de manière répétée, elle sera beaucoup plus rapide. N'oubliez pas non plus que Java et C# sont des langages fortement typés, l'optimiseur peut donc faire davantage d'hypothèses sur le code.

« Parce que c'est un langage typé dynamiquement »

Les langages de type "Static type" nécessitent que le type d'une variable soit précisé lors de sa définition, comme C, C++, Java, C# et Go, etc.

Bien qu'il existe aussi la notion de type dans les langages typés dynamiquement, le type des variables est dynamique.

a = 1
a = "foo"

Dans cet exemple, Python définit une deuxième variable de même nom et type str, tout en libérant la mémoire occupée par la première instance de a.

Les langages typés statiques ne sont pas conçus pour torturer les gens, ils sont conçus de cette façon parce que c'est ainsi que fonctionnent les processeurs. Si une opération est finalement convertie en une simple opération binaire, les objets et les types doivent être convertis en structures de données de bas niveau.

Python fait tout cela pour vous, mais vous ne vous en êtes jamais soucié et vous n'avez pas besoin de vous en soucier.

Ne pas avoir à définir de types n'est pas la raison pour laquelle Python est lent. La conception de Python vous permet de tout rendre dynamique. Vous pouvez remplacer les méthodes objet au moment de l’exécution et corriger les appels système sous-jacents au moment de l’exécution. Presque tout est possible.

Et cette conception rend difficile l'optimisation de Python.

Alors, le typage dynamique de Python rend-il Python plus lent ?

Comparer et convertir des types coûte cher. Les langages typés dynamiquement qui vérifient le type

à chaque fois qu'ils sont lus, écrits ou référencés sont difficiles à optimiser. La raison pour laquelle de nombreuses alternatives à Python sont si rapides est qu’elles sacrifient la commodité au profit des performances.

Par exemple, Cython (http://cython.org/) combine le typage statique du C et de Python pour faire connaître les types dans le code, optimisant ainsi le code et pouvant pour obtenir une amélioration des performances 84 fois

Résumé

La principale raison pour laquelle Python est lent est sa dynamique et sa diversité. Il peut être utilisé pour résoudre une variété de problèmes, mais la plupart des problèmes ont des solutions mieux optimisées et plus rapides.

Mais les applications Python disposent également de nombreuses mesures d'optimisation, telles que l'utilisation d'outils de test de performances asynchrones, la compréhension et l'utilisation de plusieurs interprètes.

Pour les applications où le temps de démarrage n'est pas important et où le code peut bénéficier du JIT, pensez à utiliser PyPy.

Pour les parties du code où les performances sont importantes et si les variables sont principalement typées de manière statique, envisagez d'utiliser Cython.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn