IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Python 3.11 serait 3 fois plus rapide que la version 3.8 du langage


Sujet :

Python

  1. #1
    Chroniqueur Actualités
    Avatar de Bruno
    Homme Profil pro
    Rédacteur technique
    Inscrit en
    Mai 2019
    Messages
    1 838
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Rédacteur technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2019
    Messages : 1 838
    Points : 36 226
    Points
    36 226
    Par défaut Python 3.11 serait 3 fois plus rapide que la version 3.8 du langage
    Python 3.11 améliorera l'emplacement des erreurs dans les tracebacks,
    et apporte de nouvelles fonctionnalités

    L'équipe de développement de Python a annoncé le 4 octobre les améliorations et les nouvelles fonctionnalités de la version 3.11 de Python. Cette version améliore la localisation des erreurs dans les logs et optimise le formatage de style C avec un format littéral ne contenant que les codes de format %s, %r et %. Les compréhensions asynchrones sont maintenant autorisées à l'intérieur des compréhensions dans les fonctions asynchrones. Les compréhensions externes deviennent implicitement asynchrones.

    Python est un langage de programmation interprété, multi-paradigme et multi-plateformes. Il favorise la programmation impérative structurée, fonctionnelle et orientée objet. Il est doté d'un typage dynamique fort, d'une gestion automatique de la mémoire par ramasse-miettes et d'un système de gestion d'exceptions ; il est ainsi similaire à Perl, Ruby, Scheme, Smalltalk et Tcl.

    Nom : python.png
Affichages : 141211
Taille : 3,4 Ko

    Le langage Python est placé sous une licence libre proche de la licence BSD et fonctionne sur la plupart des plateformes informatiques, des smartphones aux ordinateurs, de Windows à Unix avec notamment GNU/Linux en passant par macOS, ou encore Android, iOS, et peut aussi être traduit en Java ou .NET. Il est conçu pour optimiser la productivité des programmeurs en offrant des outils de haut niveau et une syntaxe simple à utiliser. Voici, ci-dessous, quelques nouveautés apportées par la version 3.11 de Python.

    Amélioration de la localisation des erreurs dans les logs

    Lors de l'impression des traces, l'interpréteur pointe désormais vers l'expression exacte qui a causé l'erreur au lieu de la ligne. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Traceback (most recent call last):
      File "distance.py", line 11, in <module>
        print(manhattan_distance(p1, p2))
              ^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "distance.py", line 6, in manhattan_distance
        return abs(point_1.x - point_2.x) + abs(point_1.y - point_2.y)
                               ^^^^^^^^^
    AttributeError: 'NoneType' object has no attribute 'x'
    Les versions précédentes de l'interpréteur ne pointaient que sur la ligne, ce qui rendait ambiguë la question de savoir quel objet était None. Ces erreurs améliorées peuvent également être utiles lorsqu'il s'agit d'objets de dictionnaire profondément imbriqués et d'appels de fonction multiples,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Traceback (most recent call last):
      File "query.py", line 37, in <module>
        magic_arithmetic('foo')
        ^^^^^^^^^^^^^^^^^^^^^^^
      File "query.py", line 18, in magic_arithmetic
        return add_counts(x) / 25
               ^^^^^^^^^^^^^
      File "query.py", line 24, in add_counts
        return 25 + query_user(user1) + query_user(user2)
                    ^^^^^^^^^^^^^^^^^
      File "query.py", line 32, in query_user
        return 1 + query_count(db, response['a']['b']['c']['user'], retry=True)
                                   ~~~~~~~~~~~~~~~~~~^^^^^
    TypeError: 'NoneType' object is not subscriptable

    Modules améliorés

    maths

    • ajout de math.cbrt() : retourne la racine cubique de x ;
    • le comportement de deux cas particuliers de math.pow() a été modifié, par souci de cohérence avec la spécification IEEE 754. Les opérations math.pow(0.0, -math.inf) et math.pow(-0.0, -math.inf) retournent maintenant inf. Auparavant, elles indiquaient ValueError.

    opérateur
    Une nouvelle fonction operator.call a été ajoutée, telle que operator.call(obj, *args, **kwargs) == obj(*args, **kwargs).

    Système d’exploitation

    Sous Windows, os.urandom() utilise maintenant BCryptGenRandom(), au lieu de CryptGenRandom() qui est déprécié.

    sqlite3

    • il est maintenant possible de désactiver l'authorizer en passant None à set_authorizer() ;
    • le nom de collation create_collation() peut maintenant contenir n'importe quel caractère Unicode. Les noms de collation avec des caractères non valides indiquent maintenant UnicodeEncodeError au lieu de sqlite3.ProgrammingError ;
    • les exceptions sqlite3 incluent maintenant le code d'erreur SQLite comme sqlite_errorcode et le nom de l'erreur SQLite comme sqlite_errorname.

    threading

    • Sous Unix, si la fonction sem_clockwait() est disponible dans la bibliothèque C (glibc 2.30 et plus récent), la méthode threading.Lock.acquire() utilise maintenant l'horloge monotonique (time.CLOCK_MONOTONIC) pour le délai d'attente, plutôt que d'utiliser l'horloge système (time.CLOCK_REALTIME), pour ne pas être affecté par les changements d'horloge système ;
    • Sous Unix, time.sleep() utilise désormais la fonction clock_nanosleep() ou nanosleep(), si elle est disponible, qui a une résolution de 1 nanoseconde (10-9 secondes), plutôt que d'utiliser select() qui a une résolution de 1 microseconde (10-6 secondes) ;
    • Sous Windows, time.sleep() utilise désormais un timer waitable dont la résolution est de 100 nanosecondes (10-7 secondes). Auparavant, il avait une résolution de 1 milliseconde (10-3 secondes).

    Portage vers Python 3.11

    Les anciennes macros (Py_TRASHCAN_SAFE_BEGIN/Py_TRASHCAN_SAFE_END) sont désormais obsolètes. Elles doivent être remplacées par les nouvelles macros Py_TRASHCAN_BEGIN et Py_TRASHCAN_END.
    Les anciennes macros, telles que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    static void
    mytype_dealloc(mytype *p)
    {
        PyObject_GC_UnTrack(p);
        Py_TRASHCAN_SAFE_BEGIN(p);
        ...
        Py_TRASHCAN_SAFE_END
    }
    doivent migrer vers les nouvelles macros comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    static void
    mytype_dealloc(mytype *p)
    {
        PyObject_GC_UnTrack(p);
        Py_TRASHCAN_BEGIN(p, mytype_dealloc)
        ...
        Py_TRASHCAN_END
    }
    Optimisations

    • le compilateur optimise maintenant le formatage simple de style C avec un format littéral contenant seulement les codes de format %s, %r et %a et le rend aussi rapide que l'expression f-string correspondante ;
    • les exceptions "à coût zéro" sont implémentées. Le coût des instructions try est pratiquement éliminé lorsqu'aucune exception n'est levée ;
    • les appels de méthodes avec des mots-clés sont maintenant plus rapides grâce à des modifications du bytecode qui évitent de créer des instances de méthodes liées. Auparavant, cette optimisation n'était appliquée qu'aux appels de méthodes avec des arguments purement positionnels.

    Source : Python

    Et vous ?

    Quel est votre avis sur le sujet ?

    Quel amélioration vous intéresse le plus ?

    Voir aussi :

    Django 3.1 est disponible, compatible avec Python 3.6, 3.7 et 3.8 et introduit JSONField pour tous les backends de base de données supportés

    La version 3.2 du framework Django est disponible, avec la découverte automatique d'AppConfig, elle apporte de nouveaux décorateurs pour le module d'administration

    Django 2.0 est disponible en version stable, quelles sont les nouveautés dans cette version du framework Web écrit en Python ?

    JetBrains soutient Django : bénéficiez d'une remise de 30 % pour l'achat d'une licence individuelle PyCharm Professional et l'intégralité des sommes perçues seront reversées à la Fondation Django
    Contribuez au club : corrections, suggestions, critiques, ... Contactez le service news et Rédigez des actualités

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 273
    Points : 36 757
    Points
    36 757
    Par défaut
    Salut,

    Citation Envoyé par Bruno Voir le message
    Et vous ?

    Quel est votre avis sur le sujet ?
    Une version beta-test n'est pas "disponible" et même la version 3.10 n'est pas encore sortie "officiellement" (toujours en tests). A ce stade, il n'est pas exclu que certaines fonctionnalités annoncées soient retirées, quelques mineures ajoutées,...

    Et en l'état, seuls les développeurs qui ont le temps (et des environnements) pour faire des tests de non-régression ou très intéressés par quelques unes des nouvelles fonctionnalités vont y passer du temps.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre éprouvé Avatar de jvallois
    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2013
    Messages
    191
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2013
    Messages : 191
    Points : 979
    Points
    979
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Une version beta-test n'est pas "disponible" et même la version 3.10 n'est pas encore sortie "officiellement" (toujours en tests). A ce stade, il n'est pas exclu que certaines fonctionnalités annoncées soient retirées, quelques mineures ajoutées,...
    Tout à fait d'accord, sauf pour un point : la 3.10 est disponible depuis aujourd'hui : https://www.python.org/downloads/

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 273
    Points : 36 757
    Points
    36 757
    Par défaut
    Citation Envoyé par jvallois Voir le message
    Tout à fait d'accord, sauf pour un point : la 3.10 est disponible depuis aujourd'hui : https://www.python.org/downloads/
    Quand j'ai regardé hier, elle ne l'était pas encore.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre régulier
    Homme Profil pro
    indépendant
    Inscrit en
    Mai 2016
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : indépendant

    Informations forums :
    Inscription : Mai 2016
    Messages : 13
    Points : 83
    Points
    83
    Par défaut C'est bien cette meilleure localisation des erreurs, on va apprécier A+
    A+

  6. #6
    Chroniqueur Actualités
    Avatar de Bruno
    Homme Profil pro
    Rédacteur technique
    Inscrit en
    Mai 2019
    Messages
    1 838
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Rédacteur technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2019
    Messages : 1 838
    Points : 36 226
    Points
    36 226
    Par défaut Python 3.11 gagnera en performance au prix d'un peu plus de mémoire
    Python 3.11 gagnera en performance au prix d'un peu plus de mémoire,
    les gains de vitesse semblent se situer entre 10 % et 60 %

    Dans le but d’améliorer les performances du langage de programmation Python, Microsoft lance Faster CPython. Il s’agit d’un projet financé par Microsoft, dont les membres comprennent l'inventeur de Python Guido van Rossum, l'ingénieur logiciel senior de Microsoft Eric Snow, et Mark Shannon qui est sous contrat avec Microsoft en tant que responsable technique du projet. « Python est largement reconnu comme étant lent. Alors que Python n'atteindra jamais les performances des langages de bas niveau comme C, Fortran, ou même Java, nous aimerions qu'il soit compétitif avec les implémentations rapides des langages de script, comme V8 pour Javascript », déclare Mark Shannon.

    Pour être performantes, les machines virtuelles pour les langages dynamiques doivent spécialiser le code qu'elles exécutent en fonction des types et des valeurs du programme en cours d'exécution. Cette spécialisation est souvent associée aux compilateurs Just-in-time (JIT), mais elle est bénéfique même sans génération de code machine.

    Nom : python.png
Affichages : 88316
Taille : 3,1 Ko

    Notons que la spécialisation permet d'améliorer les performances, et l'adaptation permet à l'interprète de changer rapidement lorsque le modèle d'utilisation d'un programme change, limitant ainsi la quantité de travail supplémentaire causée par une mauvaise spécialisation.

    Une session prévue dans le cadre de l'événement EuroPython, la plus grande conférence Python en Europe, qui se tiendra à Dublin en juillet sera consacrée à certains des changements qui permettent d'accélérer le processus. Shannon décrira l'adaptive specializing interpreter de Python 3.11, qui est le PEP (Python Enhancement Proposal) 659. Il s'agit d'une technique appelée spécialisation qui, comme l'explique Shannon, « est généralement réalisée dans le contexte d'un compilateur, mais la recherche montre que la spécialisation dans un interpréteur peut augmenter les performances de manière significative ».

    Ce PEP propose d'utiliser un interprète adaptatif qui spécialise le code de manière dynamique, mais sur une très petite région, et qui est capable de s'adapter à une mauvaise spécialisation rapidement et à faible coût.

    « L'ajout d'un interprète spécialisé et adaptatif à CPython apportera des améliorations significatives en termes de performances. Il est difficile d'avancer des chiffres significatifs, car cela dépend beaucoup des benchmarks et de travaux qui n'ont pas encore été réalisés. Des expérimentations approfondies suggèrent des accélérations allant jusqu'à 50 %. Même si le gain de vitesse n'était que de 25 %, cela resterait une amélioration intéressante », déclare Shannon.

    « Plus précisément, nous voulons atteindre ces objectifs de performance avec CPython afin d'en faire bénéficier tous les utilisateurs de Python, y compris ceux qui ne peuvent pas utiliser PyPy ou d'autres machines virtuelles alternatives », ajoute-il. Lorsque Devclass s'est entretenu avec Pablo Galindo, membre du conseil de direction de Python et développeur principal, au sujet du nouveau profileur de mémoire Memray, il a décrit comment l'équipe Python utilise le travail de Microsoft dans la version 3.11.

    « L'une des choses que nous faisons est que nous rendons l'interpréteur plus rapide, déclare Pablo Galindo, membre du conseil de direction de Python et développeur principal. Mais il va également utiliser un peu plus de mémoire, juste un peu, parce que la plupart de ces optimisations ont une sorte de coût en mémoire, étant donné que nous devons stocker des choses pour les utiliser plus tard, ou parce que nous avons une version optimisée mais parfois, quelqu'un a besoin de demander une version non optimisée pour le débogage, donc nous devons stocker les deux. »

    « Atteindre ces objectifs de performance est un long chemin à parcourir, et nécessitera beaucoup d'efforts d'ingénierie, mais nous pouvons faire un pas significatif vers ces objectifs en accélérant l'interpréteur. La recherche universitaire et les mises en œuvre pratiques ont montré qu'un interpréteur rapide est un élément clé d'une machine virtuelle rapide », déclare Shannon.

    Accélération des machines virtuelles

    Les optimisations typiques pour les machines virtuelles sont coûteuses, de sorte qu'un long temps de "démarrage" est nécessaire pour avoir la certitude que le coût de l'optimisation est justifié. Afin d'obtenir des accélérations rapides, sans temps d'échauffement perceptible, la VM devrait spéculer que la spécialisation est justifiée même après quelques exécutions d'une fonction. Pour ce faire, l'interpréteur doit être capable d'optimiser et de désoptimiser continuellement et à moindre coût. En utilisant la spécialisation adaptative et spéculative à la granularité des instructions individuelles de la machine virtuelle, l’équipe Python a obtenu un interprète plus rapide qui génère également des informations de profilage pour des optimisations plus sophistiquées dans le futur.

    « Il existe de nombreuses façons pratiques d'accélérer une machine virtuelle pour un langage dynamique. Cependant, la spécialisation est la plus importante, à la fois en elle-même et en tant que catalyseur d'autres optimisations. Il est donc logique de concentrer nos efforts sur la spécialisation en premier lieu, si nous voulons améliorer les performances de CPython », indique l’équipe du projet Faster CPython. La spécialisation est généralement effectuée dans le contexte d'un compilateur JIT, mais des recherches montrent que la spécialisation dans un interpréteur peut améliorer les performances de manière significative, voire même dépasser celles d'un compilateur classique.

    Plusieurs méthodes ont été proposées dans la littérature académique, mais la plupart tentent d'optimiser des domaines plus grands qu'un seul bytecode. L'utilisation de domaines plus grands qu'une seule instruction nécessite un code pour gérer la désoptimisation au milieu d'un domaine. La spécialisation au niveau des bytecodes individuels rend la désoptimisation triviale, car elle ne peut pas se produire au milieu d'une région.

    En spécialisant de manière spéculative les bytecodes individuels, nous pouvons obtenir des améliorations de performance significatives sans rien d'autre que les désoptimisations les plus locales et triviales à mettre en œuvre. L'approche la plus proche de ce PEP dans la littérature est "Inline Caching meets Quickening". Ce PEP présente les avantages de la mise en cache en ligne, mais ajoute la possibilité de désoptimiser rapidement, ce qui rend les performances plus robustes dans les cas où la spécialisation échoue ou n'est pas stable.

    L'accélération due à la spécialisation est difficile à déterminer, car de nombreuses spécialisations dépendent d'autres optimisations. Les gains de vitesse semblent se situer entre 10 % et 60 %. La plupart des gains de vitesse proviennent directement de la spécialisation. Les plus grands contributeurs étant les accélérations de la recherche d'attributs, des variables globales et des appels.

    Implémentation

    Instructions adaptatives

    Chaque instruction qui bénéficierait d'une spécialisation est remplacée par une version adaptative lors du quickening. Par exemple, l'instruction LOAD_ATTR est remplacée par LOAD_ATTR_ADAPTIVE. Chaque instruction adaptative tente périodiquement de se spécialiser.

    Spécialisation

    Le bytecode CPython contient de nombreuses instructions qui représentent des opérations de haut niveau, et qui bénéficieraient d'une spécialisation. Les exemples incluent CALL, LOAD_ATTR, LOAD_GLOBAL et BINARY_ADD.

    L'introduction d'une catégorie d'instructions spécialisées pour chacune de ces instructions permet une spécialisation efficace, puisque chaque nouvelle instruction est spécialisée pour une seule tâche. Chaque famille comprendra une instruction "adaptative", qui maintient un compteur et tente de se spécialiser lorsque ce compteur atteint zéro. Chaque catégorie comprendra également une ou plusieurs instructions spécialisées qui exécutent l'équivalent de l'opération générique beaucoup plus rapidement, à condition que leurs entrées soient conformes aux prévisions.

    Chaque instruction spécialisée maintient un compteur de saturation qui est incrémenté lorsque les entrées sont conformes aux attentes. Si les entrées ne sont pas conformes aux attentes, le compteur sera décrémenté et l'opération générique sera exécutée. Si le compteur atteint la valeur minimale, l'instruction est désoptimisée en remplaçant simplement son opcode par la version adaptative.

    Données auxiliaires

    La plupart des familles d'instructions spécialisées requièrent plus d'informations que ne peut en contenir un opérande de 8 bits. Pour ce faire, un certain nombre d'entrées de 16 bits suivant immédiatement l'instruction sont utilisées pour stocker ces données. Il s'agit d'une forme de cache en ligne, un "cache de données en ligne". Les instructions non spécialisées, ou adaptatives, utiliseront la première entrée de ce cache comme compteur, et sauteront simplement les autres.

    Coûts

    Utilisation de la mémoire

    Une préoccupation évidente avec tout système qui effectue une sorte de mise en cache est : combien de mémoire supplémentaire utilise-t-il ?

    Comparaison de l'utilisation de la mémoire avec 3.10

    CPython 3.10 utilisait 2 octets par instruction, jusqu'à ce que le nombre d'exécutions atteigne ~2000 lorsqu'il alloue un autre octet par instruction et 32 octets par instruction avec un cache (LOAD_GLOBAL et LOAD_ATTR).

    Le tableau suivant montre les octets supplémentaires par instruction pour supporter l'opcache 3.10 ou l'interprète adaptatif proposé, sur une machine 64 bits.

    Nom : hot.png
Affichages : 5788
Taille : 15,4 Ko

    3.10 cold est avant que le code n'ait atteint la limite de ~2000. 3.10 hot montre l'utilisation du cache une fois que le seuil est atteint. L'utilisation relative de la mémoire dépend de la quantité de code qui est suffisamment "hot" pour déclencher la création du cache dans 3.10. Le point d'équilibre, où la mémoire utilisée par 3.10 est la même que pour 3.11, est de ~70%. Il convient également de noter que le bytecode réel n'est qu'une partie d'un objet de code. Les objets de code comprennent également des noms, des constantes et un grand nombre d'informations de débogage.

    En résumé, pour la plupart des applications où de nombreuses fonctions sont relativement inutilisées, la version 3.11 consommera plus de mémoire que la version 3.10.

    Source : Python

    Et vous ?

    Quel est votre avis sur le sujet ?

    Que pensez-vous du projet Faster CPython ?

    « La version 3.11 consommera plus de mémoire que la version 3.10 », qu’en pensez-vous ?

    Selon vous, est intéressent de gagner en performance au prix d'un peu plus de mémoire ?

    Voir aussi :

    Python 3.11 améliorera l'emplacement des erreurs dans les tracebacks et apporte de nouvelles fonctionnalités

    La version 3.2 du framework Django est disponible, avec la découverte automatique d'AppConfig, elle apporte de nouveaux décorateurs pour le module d'administration

    Django 2.0 est disponible en version stable, quelles sont les nouveautés dans cette version du framework Web écrit en Python ?

    JetBrains soutient Django : bénéficiez d'une remise de 30 % pour l'achat d'une licence individuelle PyCharm Professional et l'intégralité des sommes perçues seront reversées à la Fondation Django
    Contribuez au club : corrections, suggestions, critiques, ... Contactez le service news et Rédigez des actualités

  7. #7
    Chroniqueur Actualités

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Mars 2013
    Messages
    8 428
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Mars 2013
    Messages : 8 428
    Points : 197 298
    Points
    197 298
    Par défaut La première version bêta de Python 3.11 est disponible et s'accompagne d'une meilleure gestion des erreurs
    La première version bêta de Python 3.11 est disponible et s'accompagne d'une meilleure gestion des erreurs,
    de la prise en charge de toml et d'améliorations pour la programmation asynchrone

    Meilleure gestion des erreurs

    Python 3.10 nous a donné de meilleurs messages d'erreur à divers égards, mais Python 3.11 vise à les améliorer encore plus. Certaines des choses les plus importantes qui sont ajoutées aux messages d'erreur dans Python 3.11 sont :

    Emplacements exacts des erreurs dans les retraçages

    Jusqu'à présent, dans un traçage, la seule information que vous obteniez sur l'endroit où une exception a été déclenchée était la ligne. Le problème aurait pu être n'importe où sur la ligne, donc parfois cette information n'était pas suffisante.

    Voici un exemple*:

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    def get_margin(data):
        margin = data['profits']['monthly'] / 10 + data['profits']['yearly'] / 2
        return margin
     
    data = {
        'profits': {
            'monthly': 0.82,
            'yearly': None,
        },
        'losses': {
            'monthly': 0.23,
            'yearly': 1.38,
        },
    }
    print(get_margin(data))

    Ce code génère une erreur, car l'un de ces champs dans le dictionnaire est None. Voici ce que nous obtenons*:

    Citation Envoyé par Affichage à l'écran
    Traceback (most recent call last):
    File "/Users/tusharsadhwani/code/marvin-python/mytest.py", line 15, in <module>
    print(get_margin(data))
    File "/Users/tusharsadhwani/code/marvin-python/mytest.py", line 2, in print_margin
    margin = data['profits']['monthly'] / 10 + data['profits']['yearly'] / 2
    TypeError: unsupported operand type(s) for /: 'NoneType' and 'int'
    Mais il est impossible de dire par le retraçage lui-même, quelle partie du calcul a causé l'erreur.

    Sur la version 3.11 cependant :

    Citation Envoyé par Affichage à l'écran
    Traceback (most recent call last):
    File "asd.py", line 15, in <module>
    print(get_margin(data))
    ^^^^^^^^^^^^^^^^
    File "asd.py", line 2, in print_margin
    margin = data['profits']['monthly'] / 10 + data['profits']['yearly'] / 2
    ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
    TypeError: unsupported operand type(s) for /: 'NoneType' and 'int'
    Il est évident que data['profits']['yearly'] était None.

    Pour pouvoir restituer ces informations, les données end_line et end_col ont été ajoutées aux objets de code Python. Vous pouvez également accéder à ces informations directement via la méthode obj.__code__.co_positions().

    Les notes pour les exceptions

    Pour rendre les traces encore plus riches en contexte, Python 3.11 vous permet d'ajouter des notes aux objets d'exception, qui sont stockées dans les exceptions et affichées lorsque l'exception est déclenchée.

    Prenez ce code par exemple, où nous ajoutons des informations importantes sur une logique de conversion de données d'API*:

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    def get_seconds(data):
        try:
            milliseconds = float(data['milliseconds'])
        except ValueError as exc:
            exc.add_note(
                "The time field should always be a number, this is a critial bug. "
                "Please report this to the backend team immediately."
            )
            raise  # re-raises the exception, instead of silencing it
     
        seconds = milliseconds / 1000
        return seconds
     
    get_seconds({'milliseconds': 'foo'})  # 'foo' is not a number!

    Cette note ajoutée est imprimée juste en dessous du message d'exception*:

    Citation Envoyé par Affichage à l'écran
    Traceback (most recent call last):
    File "asd.py", line 14, in <module>
    get_seconds({"milliseconds": "foo"})
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "asd.py", line 3, in get_seconds
    milliseconds = float(data["milliseconds"])
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ValueError: could not convert string to float: 'foo'
    The time field should always be a number, this is a critial bug. Please report this to the backend team immediately.
    Prise en charge toml intégrée

    La bibliothèque standard a maintenant un support intégré pour lire les fichiers TOML, en utilisant le module tomllib*:

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    import tomllib
     
    with open('.deepsource.toml', 'rb') as file:
        data = tomllib.load(file)

    tomllib est en fait basé sur une bibliothèque d'analyse TOML open source appelée tomli. Et actuellement, seule la lecture des fichiers TOML est prise en charge. Si vous devez plutôt écrire des données dans un fichier TOML, envisagez d'utiliser le package tomli-w.

    Groupes de travail asynchrones

    Lorsque vous faites de la programmation asynchrone, vous rencontrez souvent des situations où vous devez déclencher de nombreuses tâches à exécuter simultanément, puis prendre des mesures lorsqu'elles sont terminées. Par exemple, télécharger un tas d'images en parallèle, puis les regrouper dans un fichier zip à la fin.

    Pour ce faire, vous devez collecter des tâches et les transmettre à asyncio.gather. Voici un exemple simple de tâches exécutées en parallèle avec la fonction de gather*:

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    import asyncio
     
    async def simulate_flight(city, departure_time, duration):
        await asyncio.sleep(departure_time)
        print(f"Flight for {city} departing at {departure_time}PM")
     
        await asyncio.sleep(duration)
        print(f"Flight for {city} arrived.")
     
     
    flight_schedule = {
        'boston': [3, 2],
        'detroit': [7, 4],
        'new york': [1, 9],
    }
     
    async def main():
        tasks = []
        for city, (departure_time, duration) in flight_schedule.items():
            tasks.append(simulate_flight(city, departure_time, duration))
     
        await asyncio.gather(*tasks)
        print("Simulations done.")
     
    asyncio.run(main())

    Mais devoir maintenir une liste des tâches soi-même pour pouvoir les attendre est un peu maladroit. Aussi, une nouvelle API est ajoutée à asyncio appelée Groupes de tâches*:

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    import asyncio
     
    async def simulate_flight(city, departure_time, duration):
        await asyncio.sleep(departure_time)
        print(f"Flight for {city} departing at {departure_time}PM")
     
        await asyncio.sleep(duration)
        print(f"Flight for {city} arrived.")
     
     
    flight_schedule = {
        'boston': [3, 2],
        'detroit': [7, 4],
        'new york': [1, 9],
    }
     
    async def main():
        async with asyncio.TaskGroup() as tg:
            for city, (departure_time, duration) in flight_schedule.items():
                tg.create_task(simulate_flight(city, departure_time, duration))
     
        print("Simulations done.")
     
    asyncio.run(main())

    Lorsque le gestionnaire de contexte asyncio.TaskGroup() se ferme, il s'assure que toutes les tâches créées à l'intérieur ont fini de s'exécuter.

    Nom : python.png
Affichages : 16877
Taille : 12,5 Ko

    Groupes d'exceptions

    Une fonctionnalité similaire a également été ajoutée pour la gestion des exceptions dans les tâches asynchrones, appelées groupes d'exceptions.

    Supposons que de nombreuses tâches asynchrones s'exécutent ensemble et que certaines d'entre elles génèrent des erreurs. Actuellement, le système de gestion des exceptions de Python ne fonctionne pas bien dans ce scénario.

    Voici une courte démo de ce à quoi cela ressemble avec 3 tâches simultanées qui ont planté*:

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import asyncio
     
    def bad_task():
        raise ValueError("oops")
     
    async def main():
        tasks = []
        for _ in range(3):
            tasks.append(asyncio.create_task(bad_task()))
     
        await asyncio.gather(*tasks)
     
    asyncio.run(main())

    Lorsque vous exécutez ce code*:

    Citation Envoyé par Affichage à l'écran
    $ python asd.py
    Traceback (most recent call last):
    File "asd.py", line 13, in <module>
    asyncio.run(main())
    File "/usr/bin/python3.8/lib/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
    File "/usr/bin/python3.8/lib/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
    File "asd.py", line 9, in main
    tasks.append(asyncio.create_task(bad_task()))
    File "asd.py", line 4, in bad_task
    raise ValueError("oops")
    ValueError: oops
    Rien n'indique que 3 de ces tâches s'exécutaient ensemble. Dès que la première échoue, elle fait planter tout le programme.

    Mais en Python 3.11, le comportement est un peu meilleur*:

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    import asyncio
     
    async def bad_task():
        raise ValueError("oops")
     
    async def main():
        async with asyncio.TaskGroup() as tg:
            for _ in range(3):
                tg.create_task(bad_task())
     
    asyncio.run(main())

    Citation Envoyé par Affichage à l'écran
    $ python asd.py
    + Exception Group Traceback (most recent call last):
    | File "<stdin>", line 1, in <module>
    | File "/usr/local/lib/python3.11/asyncio/runners.py", line 181, in run
    | return runner.run(main)
    | ^^^^^^^^^^^^^^^^
    | File "/usr/local/lib/python3.11/asyncio/runners.py", line 115, in run
    | return self._loop.run_until_complete(task)
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | File "/usr/local/lib/python3.11/asyncio/base_events.py", line 650, in run_until_complete
    | return future.result()
    | ^^^^^^^^^^^^^^^
    | File "<stdin>", line 2, in main
    | File "/usr/local/lib/python3.11/asyncio/taskgroups.py", line 139, in __aexit__
    | raise me from None
    | ^^^^^^^^^^^^^^^^^^
    | ExceptionGroup: unhandled errors in a TaskGroup (3 sub-exceptions)
    +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    | File "<stdin>", line 2, in bad_task
    | ValueError: oops
    +---------------- 2 ----------------
    | Traceback (most recent call last):
    | File "<stdin>", line 2, in bad_task
    | ValueError: oops
    +---------------- 3 ----------------
    | Traceback (most recent call last):
    | File "<stdin>", line 2, in bad_task
    | ValueError: oops
    +------------------------------------
    L'exception nous indique maintenant que trois erreurs ont été générées, dans une structure appelée ExceptionGroup.

    La gestion des exceptions avec ces groupes d'exceptions est également intéressante, vous pouvez soit faire except ExceptionGroup pour intercepter toutes les exceptions en une seule fois :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    try:
        asyncio.run(main())
    except ExceptionGroup as eg:
        print(f"Caught exceptions: {eg}")

    Citation Envoyé par Affichage à l'écran
    $ python asd.py
    Caught exceptions: unhandled errors in a TaskGroup (3 sub-exceptions)
    Ou vous pouvez les intercepter en fonction du type d'exception, en utilisant la nouvelle syntaxe except**:

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    try:
        asyncio.run(main())
    except* ValueError as eg:
        print(f"Caught ValueErrors: {eg}")

    Citation Envoyé par Affichage à l'écran
    $ python asd.py
    Caught ValueErrors: unhandled errors in a TaskGroup (3 sub-exceptions)
    Améliorations apportées au module typing

    Le module typing a vu beaucoup de mises à jour intéressantes dans cette version. Voici quelques-uns des plus intéressantes :

    Génériques variadiques

    La prise en charge des génériques variadiques a été ajoutée au module typing dans Python 3.11.

    Cela signifie que vous pouvez désormais définir des types génériques pouvant contenir un nombre arbitraire de types. Il est utile pour définir des méthodes génériques pour les données multidimensionnelles.

    Par exemple:

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    from typing import Generic
    from typing_extensions import TypeVarTuple, Unpack
     
    Shape = TypeVarTuple('Shape')
     
    class Array(Generic[Unpack[Shape]]):
        ...
     
    # holds 1 dimensional data, like a regular list
    items: Array[int] = Array()
     
    # holds 3 dimensional data, for example, X axis, Y axis and value
    market_prices: Array[int, int, float] = Array()
     
    # This function takes in an `Array` of any shape, and returns the same shape
    def double(array: Array[Unpack[Shape]]) -> Array[Unpack[Shape]]:
        ...
     
    # This function takes an N+2 dimensional array and reduces it to an N dimensional one
    def get_values(array: Array[int, int, *Shape]) -> Array[*Shape]:
        ...
     
    # For example:
    vector_space: Array[int, int, complex] = Array()
    reveal_type(get_values(vector_space))  # revealed type is Array[complex]

    Les génériques variadiques peuvent être très utiles pour définir des fonctions qui mappent sur des données à N dimensions. Cette fonctionnalité peut être très utile pour la vérification de type des bases de code qui s'appuient sur des bibliothèques de science des données telles que numpy ou tensorflow.

    L'équipe responsable du développement de Python explique que : « La nouvelle syntaxe Generic[*Shape] n'est prise en charge que dans Python 3.11. Pour utiliser cette fonctionnalité dans Python 3.10 et versions antérieures, vous pouvez utiliser la fonction intégrée typing.Unpack à la place de Generic[Unpack[Shape]] ».

    singledispatch prend désormais en charge les unions

    functools.singledispatch est un moyen pratique de surcharger les fonctions en Python, basé sur des indications de type. Cela fonctionne en définissant une fonction générique et en se servant de @singledispatch. Ensuite, vous pouvez définir des variantes spécialisées de cette fonction, en fonction du type des arguments de la fonction*:

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    from functools import singledispatch
     
     
    @singledispatch
    def half(x):
        """Returns the half of a number"""
        return x / 2
     
    @half.register
    def _(x: int):
        """For integers, return an integer"""
        return x // 2
     
    @half.register
    def _(x: list):
        """For a list of items, get the first half of it."""
        list_length = len(x)
        return x[: list_length // 2]
     
                                # Outputs:
    print(half(3.6))            # 1.8
    print(half(15))             # 7
    print(half([1, 2, 3, 4]))   # [1, 2]

    En inspectant le type donné aux arguments de la fonction, singledispatch peut créer des fonctions génériques, fournissant une manière non orientée objet de faire la surcharge de fonction.

    Mais ce sont toutes de vieilles nouvelles. Ce que Python 3.11 apporte, c'est que maintenant, vous pouvez passer des types d'union pour ces arguments. Par exemple, pour enregistrer une fonction pour tous les types de nombres, vous deviez auparavant le faire séparément pour chaque type, tel que float, complex ou Decimal :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @half.register
    def _(x: float):
        return x / 2
     
    @half.register
    def _(x: complex):
        return x / 2
     
    @half.register
    def _(x: decimal.Decimal):
        return x / 2

    Mais maintenant, vous pouvez tous les spécifier dans une Union*:

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    @half.register
    def _(x: float | complex | decimal.Decimal):
        return x / 2

    Et le code fonctionnera exactement comme prévu.

    Le type self

    Auparavant, si vous deviez définir une méthode de classe qui renvoyait un objet de la classe elle-même, ajouter des types pour cela était un peu bizarre, cela ressemblerait à ceci*:

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    from typing import TypeVar
     
    T = TypeVar('T', bound=type)
     
    class Circle:
        def __init__(self, radius: int) -> None:
            self.radius = radius
     
        @classmethod
        def from_diameter(cls: T, diameter) -> T:
            circle = cls(radius=diameter/2)
            return circle

    Pour pouvoir dire qu'une méthode retourne le même type que la classe elle-même, il fallait définir un TypeVar, et dire que la méthode retourne le même type T que la classe actuelle elle-même.

    Mais avec le type Self, rien de tout cela n'est nécessaire*:

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from typing import Self
     
    class Circle:
        def __init__(self, radius: int) -> None:
            self.radius = radius
     
        @classmethod
        def from_diameter(cls, diameter) -> Self:
            circle = cls(radius=diameter/2)
            return circle

    Required[] and NotRequired[]

    TypedDict est vraiment utile pour ajouter des informations de type à une base de code qui utilise beaucoup de dictionnaires pour stocker des données. Voici comment vous pouvez les utiliser*:

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    from typing import TypedDict
     
    class User(TypedDict):
        name: str
        age: int
     
    user : User = {'name': "Alice", 'age': 31}
    reveal_type(user['age'])  # revealed type is 'int'

    Cependant, TypedDicts avait une limitation, où vous ne pouviez pas avoir de paramètres facultatifs dans un dictionnaire, un peu comme les paramètres par défaut dans les définitions de fonction.

    Par exemple, vous pouvez le faire avec un NamedTuple*:

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    from typing import NamedTuple
     
    class User(NamedTuple):
        name: str
        age: int
        married: bool = False
     
    marie = User(name='Marie', age=29, married=True)
    fredrick = User(name='Fredrick', age=17)  # 'married' is False by default

    Cela n'était pas possible avec un TypedDict (au moins sans définir plusieurs de ces types TypedDict). Mais maintenant, vous pouvez marquer n'importe quel champ comme NotRequired, pour signaler qu'il est normal que le dictionnaire n'ait pas ce champ*:

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    from typing import TypedDict, NotRequired
     
    class User(TypedDict):
        name: str
        age: int
        married: NotRequired[bool]
     
    marie: User = {'name': 'Marie', 'age': 29, 'married': True}
    fredrick : User = {'name': 'Fredrick', 'age': 17}  # 'married' is not required

    NotRequired est plus utile lorsque la plupart des champs de votre dictionnaire sont obligatoires, avec quelques champs non obligatoires. Mais, dans le cas contraire, vous pouvez dire à TypedDict de traiter chaque champ comme non requis par défaut, puis d'utiliser Required pour marquer les champs réellement requis.

    Par exemple, c'est le même que le code précédent*:

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from typing import TypedDict, Required
     
    # `total=False` means all fields are not required by default
    class User(TypedDict, total=False):
        name: Required[str]
        age: Required[int]
        married: bool  # now this is optional
     
    marie: User = {'name': 'Marie', 'age': 29, 'married': True}
    fredrick : User = {'name': 'Fredrick', 'age': 17}  # 'married' is not required

    contextlib.chdir

    contextlib a un petit ajout, qui est un gestionnaire de contexte appelé chdir. Tout ce qu'il fait est de remplacer le répertoire de travail actuel par le répertoire spécifié dans le gestionnaire de contexte et de le remettre à ce qu'il était avant lorsqu'il se ferme.

    Un cas d'utilisation potentiel peut être de rediriger vers où vous écrivez les journaux*:

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import os
     
    def write_logs(logs):
        with open('output.log', 'w') as file:
            file.write(logs)
     
     
    def foo():
        print("Scanning files...")
        files = os.listdir(os.curdir)  # lists files in current directory
        logs = do_scan(files)
     
        print("Writing logs to /tmp...")
        with contextlib.chdir('/tmp'):
            write_logs(logs)
     
        print("Deleting files...")
        files = os.listdir(os.curdir)
        do_delete(files)

    De cette façon, vous n'avez pas à vous soucier de modifier et de rétablir manuellement le répertoire actuel, le gestionnaire de contexte le fera pour vous.

    Source : annonce Python 3.11 bêta

    Voir aussi :

    La prochaine version de l'interpréteur Python standard, CPython, va s'accompagner d'améliorations significatives des performances, ont annoncé les développeurs durant la PyCon
    Contribuez au club : Corrections, suggestions, critiques, ... : Contactez le service news et Rédigez des actualités

  8. #8
    Chroniqueur Actualités
    Avatar de Bruno
    Homme Profil pro
    Rédacteur technique
    Inscrit en
    Mai 2019
    Messages
    1 838
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Rédacteur technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2019
    Messages : 1 838
    Points : 36 226
    Points
    36 226
    Par défaut Python 3.11 est en moyenne 25 % plus rapide que 3.10
    Python 3.11 est en moyenne 25 % plus rapide que 3.10,
    compilé avec GCC sur Ubuntu Linux, l'accélération peut aller de 10 à 60 %

    Python 3.11 est–il vraiment le Python le plus rapide ? Une chose est sûre, CPython 3.11 est en moyenne 25 % plus rapide que CPython 3.10 lorsqu'il est mesuré avec la suite de benchmark pyperformance, et compilé avec GCC sur Ubuntu Linux. En fonction de la charge de travail, l'accélération peut atteindre 10 à 60 %. L'équipe de développement de Python a annoncé le 4 octobre les améliorations et les nouvelles fonctionnalités de la version 3.11 de Python. Dans le but d’améliorer les performances du langage de programmation Python, Microsoft a lancé Faster CPython.

    Il s’agit d’un projet financé par Microsoft, dont les membres comprennent l'inventeur de Python Guido van Rossum, l'ingénieur logiciel senior de Microsoft Eric Snow, et Mark Shannon qui est sous contrat avec Microsoft en tant que responsable technique du projet. « Python est largement reconnu comme étant lent. Alors que Python n'atteindra jamais les performances des langages de bas niveau comme C, Fortran, ou même Java, nous aimerions qu'il soit compétitif avec les implémentations rapides des langages de script, comme V8 pour Javascript », déclare Mark Shannon.

    Nom : python.png
Affichages : 140081
Taille : 3,1 Ko

    Python est un langage de programmation interprété, multi-paradigme et multi-plateformes. Il favorise la programmation impérative structurée, fonctionnelle et orientée objet. Il est doté d'un typage dynamique fort, d'une gestion automatique de la mémoire par ramasse-miettes et d'un système de gestion d'exceptions ; il est ainsi similaire à Perl, Ruby, Scheme, Smalltalk et Tcl.

    Pour être performantes, les machines virtuelles pour les langages dynamiques doivent spécialiser le code qu'elles exécutent en fonction des types et des valeurs du programme en cours d'exécution. Cette spécialisation est souvent associée aux compilateurs Just-in-time (JIT), mais elle est bénéfique même sans génération de code machine. Le projet Faster CPython se concentre sur deux domaines majeurs de Python : un démarrage et une exécution plus rapides.

    Notons que la spécialisation permet d'améliorer les performances, et l'adaptation permet à l'interprète de changer rapidement lorsque le modèle d'utilisation d'un programme change, limitant ainsi la quantité de travail supplémentaire causée par une mauvaise spécialisation.

    Démarrage plus rapide

    Python met en cache le bytecode dans le répertoire __pycache__ pour accélérer le chargement des modules. Dans la version 3.10, l'exécution des modules Python ressemblait à ceci :

    Read __pycache__ -> Unmarshal -> Heap allocated code object -> Evaluate

    Dans Python 3.11, les modules de base essentiels au démarrage de Python sont "bloqués". Cela signifie que leurs objets de code (et bytecode) sont alloués statiquement par l'interpréteur. Cela réduit les étapes du processus d'exécution des modules à ceci :

    Statically allocated code object -> Evaluate

    Le démarrage de l'interpréteur est désormais 10 à 15 % plus rapide dans Python 3.11. Cela a un impact important pour les programmes à courte durée d'exécution utilisant Python. Exécution plus rapide Les frames Python sont créés chaque fois que Python appelle une fonction Python. Cette trame contient des informations sur l'exécution. Les nouvelles optimisations des frames sont les suivantes :

    • Rationalisation du processus de création de trames ;
    • Éviter l'allocation de mémoire en réutilisant généreusement l'espace de trame sur la pile C ;
    • Rationalisation de la structure interne de la trame pour qu'elle ne contienne que les informations essentielles. Les frames contenaient auparavant des informations supplémentaires de débogage et de gestion de la mémoire.

    Les objets frame de l'ancien style ne sont maintenant créés que sur demande des débogueurs ou des fonctions d'introspection Python telles que sys._getframe ou inspect.currentframe. Pour la plupart du code utilisateur, aucun objet frame n'est créé du tout. En conséquence, presque tous les appels de fonctions Python ont été accélérés de manière significative. Nous avons mesuré une accélération de 3 à 7 % dans pyperformance.

    Lors d'un appel de fonction Python, Python appelle une fonction C évaluatrice pour interpréter le code de cette fonction. Cela limite efficacement la récursion Python pure à ce qui est fiable pour la pile C. Avec 3.11, lorsque CPython détecte un code Python appelant une autre fonction Python, il crée un nouveau frame et "saute" vers le nouveau code à l'intérieur du nouveau frame. Cela évite d'appeler la fonction d'interprétation C.

    Faster CPython explore les optimisations pour CPython. Comme dit précédemment, l'équipe principale est financée par Microsoft pour travailler sur ce projet à temps plein. Pablo Galindo Salgado est également financé par Bloomberg LP pour travailler sur le projet à temps partiel. Enfin, de nombreux contributeurs sont des bénévoles de la communauté.

    Le langage Python est placé sous une licence libre proche de la licence BSD et fonctionne sur la plupart des plateformes informatiques, des smartphones aux ordinateurs, de Windows à Unix avec notamment GNU/Linux en passant par macOS, ou encore Android, iOS, et peut aussi être traduit en Java ou .NET. Il est conçu pour optimiser la productivité des programmeurs en offrant des outils de haut niveau et une syntaxe simple à utiliser.

    La plupart des appels de fonctions Python ne consomment plus d'espace dans la pile C. Cela accélère la plupart de ces appels. Cela accélère la plupart de ces appels. Dans les fonctions récursives simples comme fibonacci ou factorielle, une accélération de 1,7x a été observée. Cela signifie également que les fonctions récursives peuvent récurer beaucoup plus profondément (si l'utilisateur augmente la limite de récursion). Nous avons mesuré une amélioration de 1 à 3 % de la performance de py.

    « L'ajout d'un interprète spécialisé et adaptatif à CPython apportera des améliorations significatives en termes de performances. Il est difficile d'avancer des chiffres significatifs, car cela dépend beaucoup des benchmarks et de travaux qui n'ont pas encore été réalisés. Des expérimentations approfondies suggèrent des accélérations allant jusqu'à 50 %. Même si le gain de vitesse n'était que de 25 %, cela resterait une amélioration intéressante », déclare Shannon.

    « Plus précisément, nous voulons atteindre ces objectifs de performance avec CPython afin d'en faire bénéficier tous les utilisateurs de Python, y compris ceux qui ne peuvent pas utiliser PyPy ou d'autres machines virtuelles alternatives », ajoute-t-il. Lorsque Devclass s'est entretenu avec Pablo Galindo, membre du conseil de direction de Python et développeur principal, au sujet du nouveau profileur de mémoire Memray, il a décrit comment l'équipe Python utilise le travail de Microsoft dans la version 3.11.

    « L'une des choses que nous faisons est que nous rendons l'interpréteur plus rapide, déclare Pablo Galindo, membre du conseil de direction de Python et développeur principal. Mais il va également utiliser un peu plus de mémoire, juste un peu, parce que la plupart de ces optimisations ont une sorte de coût en mémoire, étant donné que nous devons stocker des choses pour les utiliser plus tard, ou parce que nous avons une version optimisée mais parfois, quelqu'un a besoin de demander une version non optimisée pour le débogage, donc nous devons stocker les deux. »

    PEP 659 : spécialisation de l'interpréteur adaptatif

    Le PEP 659 est l'un des éléments clés du projet Faster CPython. L'idée générale est que, bien que Python soit un langage dynamique, la plupart du code comporte des régions où les objets et les types changent rarement. Ce concept est connu sous le nom de stabilité des types. Au moment de l'exécution, Python essaie de rechercher des modèles communs et la stabilité des types dans le code en cours d'exécution. Python remplace alors l'opération en cours par une opération plus spécialisée.

    Cette opération spécialisée utilise des chemins rapides disponibles uniquement pour ces cas d'utilisation/types, qui sont généralement plus performants que leurs équivalents génériques. Cela fait également appel à un autre concept appelé "inline caching", dans lequel Python met en cache les résultats des opérations coûteuses directement dans le bytecode. Le spécialisateur combinera également certaines paires d'instructions communes en une super-instruction. Cela réduit l'overhead pendant l'exécution.

    Python ne se spécialise que lorsqu'il voit du code "hot" (exécuté plusieurs fois). Cela évite à Python de perdre du temps pour du code "run-once". Python peut également se déspécialiser lorsque le code est trop dynamique ou lorsque l'utilisation change. La spécialisation est tentée périodiquement, et les tentatives de spécialisation ne sont pas trop coûteuses. Cela permet à la spécialisation de s'adapter aux nouvelles circonstances.

    Le projet pyperformance a pour but d'être une source faisant autorité en matière de benchmarks pour toutes les implémentations de Python. L'accent est mis sur les benchmarks du monde réel, plutôt que sur les benchmarks synthétiques, en utilisant des applications complètes lorsque cela est possible.

    Source : Python

    Et vous ?

    « Python 3.11 est en moyenne 25 % plus rapide que 3.10 », êtes-vous d'avis ?

    Que pensez-vous de Python 11 ?

    Avez-vous une expérience avec Python ?

    Êtes-vous pour ou contre la suppression du Global Interpreter Lock ?

    Voir aussi :

    Python 3.11 améliorera l'emplacement des erreurs dans les tracebacks et apporte de nouvelles fonctionnalités

    La version 3.2 du framework Django est disponible, avec la découverte automatique d'AppConfig, elle apporte de nouveaux décorateurs pour le module d'administration

    Django 2.0 est disponible en version stable, quelles sont les nouveautés dans cette version du framework Web écrit en Python ?

    JetBrains soutient Django : bénéficiez d'une remise de 30 % pour l'achat d'une licence individuelle PyCharm Professional et l'intégralité des sommes perçues seront reversées à la Fondation Django
    Contribuez au club : corrections, suggestions, critiques, ... Contactez le service news et Rédigez des actualités

  9. #9
    Chroniqueur Actualités

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Mars 2013
    Messages
    8 428
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Mars 2013
    Messages : 8 428
    Points : 197 298
    Points
    197 298
    Par défaut Python 3.11 est disponible et s'accompagne d'une amélioration de la vitesse, de meilleures gestion des erreurs
    Python 3.11 est disponible et s'accompagne d'une amélioration de la vitesse, de meilleures gestion des erreurs,
    du type self ainsi que des notes d'exception

    Le journal des modifications de Python 3.11 consiste en une longue liste de corrections de bogues, d'améliorations et d'ajouts, dont la plupart ne seront peut-être même pas remarqués. Cependant, quelques nouvelles fonctionnalités critiques pourraient considérablement améliorer votre flux de travail Python, notamment l'amélioration de la vitesse, de meilleures gestion des erreurs (notamment au niveau des messages), des notes pour les exceptions, du type self (que vous pouvez ajouter à la définition d'une fonction si sa valeur de retour est du même type que la classe elle-même ou une nouvelle instance de la classe), des améliorations des bibliothèques standard.


    Un langage qui gagne en popularité

    Depuis un an déjà, Python occupe la première place de l'index TIOBE. Lors de son arrivée en pole position, Paul Jansen, PDG de Tiobe, notait déjà que c'était une première en 20 ans :

    « Pour la première fois depuis plus de 20 ans, nous avons un nouveau chef de file : le langage de programmation Python. L'hégémonie de longue date de Java et C est terminée. Python, qui a commencé comme un simple langage de script, comme alternative à Perl, est devenu mature. Sa facilité d'apprentissage, son énorme quantité de bibliothèques et son utilisation répandue dans toutes sortes de domaines en ont fait le langage de programmation le plus populaire d'aujourd'hui. Félicitations Guido van Rossum ! Proficiat ! »

    Python est un langage de programmation interprété, multi-paradigme et multi-plateformes. Il favorise la programmation impérative structurée, fonctionnelle et orientée objet. Il est doté d'un typage dynamique fort, d'une gestion automatique de la mémoire par récupérateur de mémoire et d'un système de gestion d'exceptions ; il ressemble ainsi à Perl, Ruby, Scheme, Smalltalk et Tcl.

    Python gagne en popularité ces temps-ci, en partie à cause de l'essor de la science des données et de son écosystème de bibliothèques logicielles d'apprentissage automatique comme NumPy, Pandas, TensorFlow de Google et PyTorch de Facebook.

    En effet, Python continuerait d'être la norme et la compétence la plus recherchée dans le domaine de la science des données, dépassant de loin les autres technologies et outils, comme R, SAS, Hadoop et Java. C'est ce que suggère une analyse réalisée par Terence Shin, un spécialiste des données, qui a indiqué que l'adoption de Python pour la science des données continue de croître alors même que le langage R, plus spécialisé, est en déclin. Bien entendu, cela ne veut pas dire que les spécialistes des données vont abandonner R de sitôt. L'on continuera probablement à voir Python et R utilisés pour leurs forces respectives.

    Nom : un.png
Affichages : 202697
Taille : 40,2 Ko

    Python 3.11 gagne en rapidité grâce à un interpréteur adaptatif spécialisé

    Au cours de l'année écoulée, Microsoft a financé une équipe - dirigée par les principaux développeurs Mark Shannon et Guido van Rossum - pour travailler à plein temps sur l'accélération de CPython, la nouvelle version de l'interpréteur Python standard. Avec un financement supplémentaire de Bloomberg et l'aide d'un large éventail d'autres contributeurs de la communauté, les résultats ont porté leurs fruits. Sur les benchmarks pyperformance au moment de la sortie de la version bêta, Python 3.11 était environ 1,25 fois plus rapide que Python 3.10, une réalisation phénoménale.

    Mais il reste encore beaucoup à faire. Lors du Python Language Summit 2022, Mark Shannon a présenté la prochaine étape du projet Faster CPython. L'avenir est rapide.

    Le premier problème soulevé par Shannon était un problème de mesures. Afin de savoir comment rendre Python plus rapide, nous devons savoir à quel point Python est actuellement lent. Mais lent à faire quoi, exactement ? Et à quel point ?

    De bons benchmarks sont essentiels pour un projet qui vise à optimiser Python pour une utilisation générale. Pour cela, l'équipe Faster CPython a besoin de l'aide de la communauté dans son ensemble. Le projet « a besoin de plus de repères », a déclaré Shannon - il doit comprendre plus précisément pourquoi la base d'utilisateurs dans son ensemble utilise Python, comment ils le font et ce qui le rend lent pour le moment (si c'est lent !) .

    Une référence, a expliqué Shannon, est « juste un programme que nous pouvons chronométrer ». Toute personne ayant une référence - ou même simplement une suggestion de référence ! – qu'elle pense être représentatif d'un projet plus vaste sur lequel elle travaille est invitée à les soumettre au suivi des problèmes du référentiel python/pyperformance sur GitHub.

    Néanmoins, l'équipe Faster CPython a de quoi s'occuper entre-temps.

    Une grande partie du travail d'optimisation dans 3.11 a été réalisée grâce à la mise en œuvre de PEP 659, un « interpréteur adaptatif spécialisé ». L'interpréteur adaptatif que Shannon et son équipe ont introduit suit les bytecodes individuels à différents moments de l'exécution d'un programme. Lorsqu'il repère une opportunité, un bytecode peut être « accéléré » : cela signifie qu'un bytecode lent, qui peut faire beaucoup de choses, est remplacé par l'interpréteur par un bytecode plus spécialisé qui est très bon pour faire une chose spécifique.

    Shannon a noté que Python a également essentiellement la même consommation de mémoire en 3.11 qu'en 3.10. C'est quelque chose sur lequel il aimerait travailler : une surcharge de mémoire plus petite signifie généralement moins d'opérations de comptage de références dans la machine virtuelle, une surcharge de collecte de mémoire plus faible et des performances plus fluides en conséquence.

    Une autre grande piste d'optimisation restante est la question des extensions C. L'interface simple de CPython avec C est son principal avantage par rapport aux autres implémentations Python telles que PyPy, où les incompatibilités avec les extensions C sont l'un des plus grands obstacles à l'adoption par les utilisateurs. Le travail d'optimisation qui a été fait dans CPython 3.11 a largement ignoré la question des modules d'extension, mais Shannon veut maintenant ouvrir la possibilité d'exposer des API de fonction de bas niveau à la machine virtuelle, réduisant ainsi le temps de communication entre le code Python et Code C.

    Meilleure gestion des erreurs

    Python 3.10 nous a donné de meilleurs messages d'erreur à divers égards, mais Python 3.11 vise à les améliorer encore plus. Certaines des choses les plus importantes qui sont ajoutées aux messages d'erreur dans Python 3.11 sont :

    Emplacements exacts des erreurs dans les retraçages

    Jusqu'à présent, dans un traçage, la seule information que vous obteniez sur l'endroit où une exception a été déclenchée était la ligne. Le problème aurait pu être n'importe où sur la ligne, donc parfois cette information n'était pas suffisante.

    Voici un exemple :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    def get_margin(data):
        margin = data['profits']['monthly'] / 10 + data['profits']['yearly'] / 2
        return margin
     
    data = {
        'profits': {
            'monthly': 0.82,
            'yearly': None,
        },
        'losses': {
            'monthly': 0.23,
            'yearly': 1.38,
        },
    }
    print(get_margin(data))

    Ce code génère une erreur, car l'un de ces champs dans le dictionnaire est None. Voici ce que nous obtenons :

    Citation Envoyé par Affichage à l'écran
    Traceback (most recent call last):
    File "/Users/tusharsadhwani/code/marvin-python/mytest.py", line 15, in <module>
    print(get_margin(data))
    File "/Users/tusharsadhwani/code/marvin-python/mytest.py", line 2, in print_margin
    margin = data['profits']['monthly'] / 10 + data['profits']['yearly'] / 2
    TypeError: unsupported operand type(s) for /: 'NoneType' and 'int'
    Mais il est impossible de dire par le retraçage lui-même, quelle partie du calcul a causé l'erreur.

    Sur la version 3.11 cependant :

    Citation Envoyé par Affichage à l'écran
    Traceback (most recent call last):
    File "asd.py", line 15, in <module>
    print(get_margin(data))
    ^^^^^^^^^^^^^^^^
    File "asd.py", line 2, in print_margin
    margin = data['profits']['monthly'] / 10 + data['profits']['yearly'] / 2
    ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
    TypeError: unsupported operand type(s) for /: 'NoneType' and 'int'
    Il est évident que data['profits']['yearly'] était None.

    Pour pouvoir restituer ces informations, les données end_line et end_col ont été ajoutées aux objets de code Python. Vous pouvez également accéder à ces informations directement via la méthode obj.__code__.co_positions().

    Les notes pour les exceptions

    Pour rendre les traces encore plus riches en contexte, Python 3.11 vous permet d'ajouter des notes aux objets d'exception, qui sont stockées dans les exceptions et affichées lorsque l'exception est déclenchée.

    Prenez ce code par exemple, où nous ajoutons des informations importantes sur une logique de conversion de données d'API :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    def get_seconds(data):
        try:
            milliseconds = float(data['milliseconds'])
        except ValueError as exc:
            exc.add_note(
                "The time field should always be a number, this is a critial bug. "
                "Please report this to the backend team immediately."
            )
            raise  # re-raises the exception, instead of silencing it
     
        seconds = milliseconds / 1000
        return seconds
     
    get_seconds({'milliseconds': 'foo'})  # 'foo' is not a number!

    Cette note ajoutée est imprimée juste en dessous du message d'exception :

    Citation Envoyé par Affichage à l'écran
    Traceback (most recent call last):
    File "asd.py", line 14, in <module>
    get_seconds({"milliseconds": "foo"})
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "asd.py", line 3, in get_seconds
    milliseconds = float(data["milliseconds"])
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ValueError: could not convert string to float: 'foo'
    The time field should always be a number, this is a critial bug. Please report this to the backend team immediately.
    Prise en charge toml intégrée

    La bibliothèque standard a maintenant un support intégré pour lire les fichiers TOML, en utilisant le module tomllib :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    import tomllib
     
    with open('.deepsource.toml', 'rb') as file:
        data = tomllib.load(file)

    tomllib est en fait basé sur une bibliothèque d'analyse TOML open source appelée tomli. Et actuellement, seule la lecture des fichiers TOML est prise en charge. Si vous devez plutôt écrire des données dans un fichier TOML, envisagez d'utiliser le package tomli-w.

    Groupes de travail asynchrones

    Lorsque vous faites de la programmation asynchrone, vous rencontrez souvent des situations où vous devez déclencher de nombreuses tâches à exécuter simultanément, puis prendre des mesures lorsqu'elles sont terminées. Par exemple, télécharger un tas d'images en parallèle, puis les regrouper dans un fichier zip à la fin.

    Pour ce faire, vous devez collecter des tâches et les transmettre à asyncio.gather. Voici un exemple simple de tâches exécutées en parallèle avec la fonction de gather :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    import asyncio
     
    async def simulate_flight(city, departure_time, duration):
        await asyncio.sleep(departure_time)
        print(f"Flight for {city} departing at {departure_time}PM")
     
        await asyncio.sleep(duration)
        print(f"Flight for {city} arrived.")
     
     
    flight_schedule = {
        'boston': [3, 2],
        'detroit': [7, 4],
        'new york': [1, 9],
    }
     
    async def main():
        tasks = []
        for city, (departure_time, duration) in flight_schedule.items():
            tasks.append(simulate_flight(city, departure_time, duration))
     
        await asyncio.gather(*tasks)
        print("Simulations done.")
     
    asyncio.run(main())

    Mais devoir maintenir une liste des tâches soi-même pour pouvoir les attendre est un peu maladroit. Aussi, une nouvelle API est ajoutée à asyncio appelée Groupes de tâches :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    import asyncio
     
    async def simulate_flight(city, departure_time, duration):
        await asyncio.sleep(departure_time)
        print(f"Flight for {city} departing at {departure_time}PM")
     
        await asyncio.sleep(duration)
        print(f"Flight for {city} arrived.")
     
     
    flight_schedule = {
        'boston': [3, 2],
        'detroit': [7, 4],
        'new york': [1, 9],
    }
     
    async def main():
        async with asyncio.TaskGroup() as tg:
            for city, (departure_time, duration) in flight_schedule.items():
                tg.create_task(simulate_flight(city, departure_time, duration))
     
        print("Simulations done.")
     
    asyncio.run(main())

    Lorsque le gestionnaire de contexte asyncio.TaskGroup() se ferme, il s'assure que toutes les tâches créées à l'intérieur ont fini de s'exécuter.

    Nom : deux.png
Affichages : 11246
Taille : 61,9 Ko

    Groupes d'exceptions

    Une fonctionnalité similaire a également été ajoutée pour la gestion des exceptions dans les tâches asynchrones, appelées groupes d'exceptions.

    Supposons que de nombreuses tâches asynchrones s'exécutent ensemble et que certaines d'entre elles génèrent des erreurs. Actuellement, le système de gestion des exceptions de Python ne fonctionne pas bien dans ce scénario.

    Voici une courte démo de ce à quoi cela ressemble avec 3 tâches simultanées qui ont planté :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import asyncio
     
    def bad_task():
        raise ValueError("oops")
     
    async def main():
        tasks = []
        for _ in range(3):
            tasks.append(asyncio.create_task(bad_task()))
     
        await asyncio.gather(*tasks)
     
    asyncio.run(main())

    Lorsque vous exécutez ce code :

    Citation Envoyé par Affichage à l'écran
    $ python asd.py
    Traceback (most recent call last):
    File "asd.py", line 13, in <module>
    asyncio.run(main())
    File "/usr/bin/python3.8/lib/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
    File "/usr/bin/python3.8/lib/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
    File "asd.py", line 9, in main
    tasks.append(asyncio.create_task(bad_task()))
    File "asd.py", line 4, in bad_task
    raise ValueError("oops")
    ValueError: oops
    Rien n'indique que 3 de ces tâches s'exécutaient ensemble. Dès que la première échoue, elle fait planter tout le programme.

    Mais en Python 3.11, le comportement est un peu meilleur :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    import asyncio
     
    async def bad_task():
        raise ValueError("oops")
     
    async def main():
        async with asyncio.TaskGroup() as tg:
            for _ in range(3):
                tg.create_task(bad_task())
     
    asyncio.run(main())

    Citation Envoyé par Affichage à l'écran
    $ python asd.py
    + Exception Group Traceback (most recent call last):
    | File "<stdin>", line 1, in <module>
    | File "/usr/local/lib/python3.11/asyncio/runners.py", line 181, in run
    | return runner.run(main)
    | ^^^^^^^^^^^^^^^^
    | File "/usr/local/lib/python3.11/asyncio/runners.py", line 115, in run
    | return self._loop.run_until_complete(task)
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | File "/usr/local/lib/python3.11/asyncio/base_events.py", line 650, in run_until_complete
    | return future.result()
    | ^^^^^^^^^^^^^^^
    | File "<stdin>", line 2, in main
    | File "/usr/local/lib/python3.11/asyncio/taskgroups.py", line 139, in __aexit__
    | raise me from None
    | ^^^^^^^^^^^^^^^^^^
    | ExceptionGroup: unhandled errors in a TaskGroup (3 sub-exceptions)
    +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    | File "<stdin>", line 2, in bad_task
    | ValueError: oops
    +---------------- 2 ----------------
    | Traceback (most recent call last):
    | File "<stdin>", line 2, in bad_task
    | ValueError: oops
    +---------------- 3 ----------------
    | Traceback (most recent call last):
    | File "<stdin>", line 2, in bad_task
    | ValueError: oops
    +------------------------------------
    L'exception nous indique maintenant que trois erreurs ont été générées, dans une structure appelée ExceptionGroup.

    La gestion des exceptions avec ces groupes d'exceptions est également intéressante, vous pouvez soit faire except ExceptionGroup pour intercepter toutes les exceptions en une seule fois :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    try:
        asyncio.run(main())
    except ExceptionGroup as eg:
        print(f"Caught exceptions: {eg}")

    Citation Envoyé par Affichage à l'écran
    $ python asd.py
    Caught exceptions: unhandled errors in a TaskGroup (3 sub-exceptions)
    Ou vous pouvez les intercepter en fonction du type d'exception, en utilisant la nouvelle syntaxe except* :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    try:
        asyncio.run(main())
    except* ValueError as eg:
        print(f"Caught ValueErrors: {eg}")

    Citation Envoyé par Affichage à l'écran
    $ python asd.py
    Caught ValueErrors: unhandled errors in a TaskGroup (3 sub-exceptions)
    Améliorations apportées au module typing

    Le module typing a vu beaucoup de mises à jour intéressantes dans cette version. Voici quelques-uns des plus intéressantes :

    Génériques variadiques

    La prise en charge des génériques variadiques a été ajoutée au module typing dans Python 3.11.

    Cela signifie que vous pouvez désormais définir des types génériques pouvant contenir un nombre arbitraire de types. Il est utile pour définir des méthodes génériques pour les données multidimensionnelles.

    Par exemple:

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    from typing import Generic
    from typing_extensions import TypeVarTuple, Unpack
     
    Shape = TypeVarTuple('Shape')
     
    class Array(Generic[Unpack[Shape]]):
        ...
     
    # holds 1 dimensional data, like a regular list
    items: Array[int] = Array()
     
    # holds 3 dimensional data, for example, X axis, Y axis and value
    market_prices: Array[int, int, float] = Array()
     
    # This function takes in an `Array` of any shape, and returns the same shape
    def double(array: Array[Unpack[Shape]]) -> Array[Unpack[Shape]]:
        ...
     
    # This function takes an N+2 dimensional array and reduces it to an N dimensional one
    def get_values(array: Array[int, int, *Shape]) -> Array[*Shape]:
        ...
     
    # For example:
    vector_space: Array[int, int, complex] = Array()
    reveal_type(get_values(vector_space))  # revealed type is Array[complex]

    Les génériques variadiques peuvent être très utiles pour définir des fonctions qui mappent sur des données à N dimensions. Cette fonctionnalité peut être très utile pour la vérification de type des bases de code qui s'appuient sur des bibliothèques de science des données telles que numpy ou tensorflow.

    L'équipe responsable du développement de Python explique que : « La nouvelle syntaxe Generic[*Shape] n'est prise en charge que dans Python 3.11. Pour utiliser cette fonctionnalité dans Python 3.10 et versions antérieures, vous pouvez utiliser la fonction intégrée typing.Unpack à la place de Generic[Unpack[Shape]] ».

    singledispatch prend désormais en charge les unions

    functools.singledispatch est un moyen pratique de surcharger les fonctions en Python, basé sur des indications de type. Cela fonctionne en définissant une fonction générique et en se servant de @singledispatch. Ensuite, vous pouvez définir des variantes spécialisées de cette fonction, en fonction du type des arguments de la fonction :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    from functools import singledispatch
     
     
    @singledispatch
    def half(x):
        """Returns the half of a number"""
        return x / 2
     
    @half.register
    def _(x: int):
        """For integers, return an integer"""
        return x // 2
     
    @half.register
    def _(x: list):
        """For a list of items, get the first half of it."""
        list_length = len(x)
        return x[: list_length // 2]
     
                                # Outputs:
    print(half(3.6))            # 1.8
    print(half(15))             # 7
    print(half([1, 2, 3, 4]))   # [1, 2]

    En inspectant le type donné aux arguments de la fonction, singledispatch peut créer des fonctions génériques, fournissant une manière non orientée objet de faire la surcharge de fonction.

    Mais ce sont toutes de vieilles nouvelles. Ce que Python 3.11 apporte, c'est que maintenant, vous pouvez passer des types d'union pour ces arguments. Par exemple, pour enregistrer une fonction pour tous les types de nombres, vous deviez auparavant le faire séparément pour chaque type, tel que float, complex ou Decimal :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @half.register
    def _(x: float):
        return x / 2
     
    @half.register
    def _(x: complex):
        return x / 2
     
    @half.register
    def _(x: decimal.Decimal):
        return x / 2

    Mais maintenant, vous pouvez tous les spécifier dans une Union :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    @half.register
    def _(x: float | complex | decimal.Decimal):
        return x / 2

    Et le code fonctionnera exactement comme prévu.

    Le type self

    Auparavant, si vous deviez définir une méthode de classe qui renvoyait un objet de la classe elle-même, ajouter des types pour cela était un peu bizarre, cela ressemblerait à ceci :

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    from typing import TypeVar
     
    T = TypeVar('T', bound=type)
     
    class Circle:
        def __init__(self, radius: int) -> None:
            self.radius = radius
     
        @classmethod
        def from_diameter(cls: T, diameter) -> T:
            circle = cls(radius=diameter/2)
            return circle

    Pour pouvoir dire qu'une méthode retourne le même type que la classe elle-même, il fallait définir un TypeVar, et dire que la méthode retourne le même type T que la classe actuelle elle-même.

    Mais avec le type Self, rien de tout cela n'est nécessaire :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from typing import Self
     
    class Circle:
        def __init__(self, radius: int) -> None:
            self.radius = radius
     
        @classmethod
        def from_diameter(cls, diameter) -> Self:
            circle = cls(radius=diameter/2)
            return circle

    Required[] and NotRequired[]

    TypedDict est vraiment utile pour ajouter des informations de type à une base de code qui utilise beaucoup de dictionnaires pour stocker des données. Voici comment vous pouvez les utiliser :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    from typing import TypedDict
     
    class User(TypedDict):
        name: str
        age: int
     
    user : User = {'name': "Alice", 'age': 31}
    reveal_type(user['age'])  # revealed type is 'int'

    Cependant, TypedDicts avait une limitation, où vous ne pouviez pas avoir de paramètres facultatifs dans un dictionnaire, un peu comme les paramètres par défaut dans les définitions de fonction.

    Par exemple, vous pouvez le faire avec un NamedTuple :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    from typing import NamedTuple
     
    class User(NamedTuple):
        name: str
        age: int
        married: bool = False
     
    marie = User(name='Marie', age=29, married=True)
    fredrick = User(name='Fredrick', age=17)  # 'married' is False by default

    Cela n'était pas possible avec un TypedDict (au moins sans définir plusieurs de ces types TypedDict). Mais maintenant, vous pouvez marquer n'importe quel champ comme NotRequired, pour signaler qu'il est normal que le dictionnaire n'ait pas ce champ :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    from typing import TypedDict, NotRequired
     
    class User(TypedDict):
        name: str
        age: int
        married: NotRequired[bool]
     
    marie: User = {'name': 'Marie', 'age': 29, 'married': True}
    fredrick : User = {'name': 'Fredrick', 'age': 17}  # 'married' is not required

    NotRequired est plus utile lorsque la plupart des champs de votre dictionnaire sont obligatoires, avec quelques champs non obligatoires. Mais, dans le cas contraire, vous pouvez dire à TypedDict de traiter chaque champ comme non requis par défaut, puis d'utiliser Required pour marquer les champs réellement requis.

    Par exemple, c'est le même que le code précédent :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from typing import TypedDict, Required
     
    # `total=False` means all fields are not required by default
    class User(TypedDict, total=False):
        name: Required[str]
        age: Required[int]
        married: bool  # now this is optional
     
    marie: User = {'name': 'Marie', 'age': 29, 'married': True}
    fredrick : User = {'name': 'Fredrick', 'age': 17}  # 'married' is not required

    contextlib.chdir

    contextlib a un petit ajout, qui est un gestionnaire de contexte appelé chdir. Tout ce qu'il fait est de remplacer le répertoire de travail actuel par le répertoire spécifié dans le gestionnaire de contexte et de le remettre à ce qu'il était avant lorsqu'il se ferme.

    Un cas d'utilisation potentiel peut être de rediriger vers où vous écrivez les journaux :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import os
     
    def write_logs(logs):
        with open('output.log', 'w') as file:
            file.write(logs)
     
     
    def foo():
        print("Scanning files...")
        files = os.listdir(os.curdir)  # lists files in current directory
        logs = do_scan(files)
     
        print("Writing logs to /tmp...")
        with contextlib.chdir('/tmp'):
            write_logs(logs)
     
        print("Deleting files...")
        files = os.listdir(os.curdir)
        do_delete(files)

    De cette façon, vous n'avez pas à vous soucier de modifier et de rétablir manuellement le répertoire actuel, le gestionnaire de contexte le fera pour vous.

    Source : note de version

    Et vous ?

    Avez-vous déjà utilisé Python ou vous en servez-vous actuellement ? Qu'en pensez-vous ?
    Quelles améliorations ou nouveauté vous intéressent le plus ?

    Voir aussi :

    JavaScript toujours devant Python et Java dans le dernier classement de RedMonk, tandis que Go et TypeScript gagnent des places
    Le langage de programmation Rust gagne en popularité parmi les développeurs et fait son entrée dans le top 20, selon Tiobe. Python, Java, C et C++ s'accaparent à eux seuls de 55% de parts de marché
    Contribuez au club : Corrections, suggestions, critiques, ... : Contactez le service news et Rédigez des actualités

  10. #10
    Chroniqueur Actualités

    Homme Profil pro
    Dirigeant
    Inscrit en
    Juin 2016
    Messages
    3 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations professionnelles :
    Activité : Dirigeant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2016
    Messages : 3 160
    Points : 66 256
    Points
    66 256
    Par défaut Python 3.11 serait 3 fois plus rapide que la version 3.8 du langage
    Python 3.11 serait 3 fois plus rapide que la version 3.8 du langage
    selon un test de performance

    Python 3.11, la dernière version langage, serait significativement plus rapide que les versions précédentes. Python 3.11 présenterait des améliorations de performance spectaculaires par rapport à Python 3.10 et aux versions antérieures. Après un test réalisé récemment, Bram Wasti, ingénieur système chez Meta, affirme que Python 3.11 est 3 fois plus rapide que la version 3.8. Wasti pense tout de même qu'il y a encore du chemin à faire en matière d'améliorations des performances.

    Python est un langage interprété populaire, mais réputé lent par rapport à des langages comme JavaScript ou C++. Mais ces dernières années, il a fait des progrès en matière de performance et plusieurs benchmarks révèlent que la version la plus récente présente une accélération notable. Selon le site officiel du langage, Python 3.11, publié il y a quelques jours, est entre 10 et 60 % plus rapide que Python 3.10. « En moyenne, nous avons mesuré une accélération de 1,25x sur la suite de benchmark standard », a écrit Pablo Galindo Salgado, membre de l'équipe de développement de Python, dans les notes de version de Python 3.11.

    Nom : zdezs.png
Affichages : 58762
Taille : 31,3 Ko

    Wasti a également réalisé un test après la sortie de Python 3.11 pour voir à quel point il était rapide par rapport aux versions précédentes, mais également par rapport à d'autres langages. À l'aide d'un MacBook doté d'une puce M1 Pro, il a exécuté un code de simulation à N corps en utilisant Python 3.8, 3.11, Bun et C++17 (-O2). Pour mémoire, une simulation à N corps donne une approximation numérique de l'évolution d'un système de corps dans lequel chaque corps interagit continuellement avec tous les autres corps. La simulation à N corps est utilisée dans de nombreux autres problèmes de calcul scientifique.

    Un exemple familier est une simulation astrophysique dans laquelle chaque corps représente une galaxie ou une étoile individuelle, et les corps s'attirent mutuellement par la force gravitationnelle. La simulation de l'écoulement turbulent des fluides et le calcul de l'illumination globale en infographie sont d'autres exemples de problèmes faisant appel à la simulation à N corps. Wasti a présenté les résultats obtenus lors du test dans un billet de blogue sur son site Web personnel. Pour exécuter cette simulation, Python 3.8 aurait mis 96,79 secondes, alors que Python 3.11 n'aurait mis que 31,98 secondes. C'est 3 fois plus rapide.

    En outre, Wasti affirme que JavaScript est une bonne base de référence pour les performances du langage. Tout comme Python, il s'agit d'un langage de script flexible à typage dynamique, qui peut être exécuté dans le terminal et qui dispose d'une interface C-API bien établie. Il note que JavaScript n'est pas exactement un outsider dans cette comparaison. Toutefois, il a choisi de faire cette comparaison, car JavaScript est également très populaire et réputé plus rapide que Python. Wasti affirme que Bun, un moteur d'exécution JavaScript rapide, aurait mis 0,768 seconde pour exécuter la simulation, soit 41 fois plus vite que Python 3.11.

    Bun permet de regrouper, transpiler, installer et exécuter des projets JavaScript et TypeScript. Il s’agit d’un runtime JavaScript avec un bundler natif, un transpiler, un task runner et un client npm intégrés. Bun est conçu pour remplacer les application ou scripts JavaScript et TypeScript sur l’ordinateur local. Il implémente nativement des centaines d'APIs Node.js et Web, y compris environ 90 % des fonctions Node-API (modules natifs), fs, path, Buffer et plus encore. L'objectif de Bun est d'exécuter la plupart des codes JavaScript en dehors des navigateurs, en apportant des améliorations de performance et de complexité à l’infrastructure.

    Le troisième langage utilisé par Wasti lors de ce test est le C++ (C++17). Il s'agit d'un langage compilé, ce qui signifie qu'il ne bénéficie pas de la commodité de Python et de JavaScript. En plus d'un typage strict et d'une syntaxe généralement moche, le C++ nécessite également une compilation préalable. Selon Wasti, il faut 0,183 seconde pour compiler le code C++ avec -O2. Ensuite, en exécutant le binaire, le C++ met 0,423 seconde à exécuter la simulation, soit 1,8 fois plus vite que JavaScript. « Pour moi, ce chiffre représente la performance "maximale" qu'un langage comme Python pourrait atteindre », a déclaré Wasti.

    « Je pense que c'est génial que Python améliore ses performances. Le langage a une syntaxe très agréable et est souvent le premier langage enseigné aux nouveaux programmeurs », a-t-il ajouté. En outre, d'autres sources estiment que Python 3.11 est une énorme amélioration dans le domaine des performances par rapport aux versions précédentes de CPython. Python 3.11 serait un grand changement pour l'augmentation des performances et pour rendre cette implémentation de facto de Python plus compétitive par rapport à Pyston et PyPy. Python 3.11 apporte également de nouvelles fonctionnalités très utiles.

    Parmi les principales fonctionnalités, citons l'amélioration du typage, l'ajout de la prise en charge des groupes de tâches avec E/S asynchrones, la localisation fine des erreurs dans les traces, les groupes d'exceptions, la prise en charge de l'analyse de TOML dans la bibliothèque standard et divers changements de typage. L'ajout le plus important parmi les nombreuses améliorations individuelles des performances dans Python 3.11 est l'"interpréteur adaptatif spécialisé". L'interpréteur tente d'analyser le code en cours d'exécution et de remplacer les bytecodes généraux par des bytecodes spécifiques au type, car le type d'un objet change rarement.

    Par exemple, les opérations binaires telles que l'addition et la soustraction peuvent être remplacées par des versions spécialisées pour les flottants, les entiers et les chaînes de caractères. Les utilisateurs n'ont pas besoin de modifier le code de leurs programmes Python pour bénéficier des gains de vitesse de Python 3.11.

    Source : Billet de blogue

    Et vous ?

    Quel est votre avis sur le sujet ?
    Pensez-vous que la simulation à N corps est pertinente pour ce test ?
    Que pensez-vous des améliorations de performances dans Python 3.11 ?

    Voir aussi

    Python 3.11 est disponible et s'accompagne d'une amélioration de la vitesse, de meilleures gestion des erreurs, du type self ainsi que des notes d'exception

    Python 3.11 est en moyenne 25 % plus rapide que 3.10, compilé avec GCC sur Ubuntu Linux, l'accélération peut aller de 10 à 60 %

    Bun, un nouveau moteur d'exécution JavaScript, livré avec un client SQLite3 rapide, il apporte un peu de concurrence pour Node et Deno

    La compilation à la volée (just-in-time) ne serait pas ergonomique, selon Abe Winter qui propose des améliorations
    Contribuez au club : corrections, suggestions, critiques, ... Contactez le service news et Rédigez des actualités

  11. #11
    Membre émérite
    Profil pro
    retraité
    Inscrit en
    Décembre 2010
    Messages
    806
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Décembre 2010
    Messages : 806
    Points : 2 306
    Points
    2 306
    Par défaut
    Le C++ a une syntaxe moche ? autant les templates à la création cela peut être effectivement compliqué, mais cela est réservé pour les cas complexes aux experts, autant pour le reste je ne trouve pas cela moche

  12. #12
    Membre extrêmement actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2022
    Messages
    755
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Août 2022
    Messages : 755
    Points : 0
    Points
    0
    Par défaut
    Citation Envoyé par archqt Voir le message
    Le C++ a une syntaxe moche ? autant les templates à la création cela peut être effectivement compliqué, mais cela est réservé pour les cas complexes aux experts, autant pour le reste je ne trouve pas cela moche
    De toute façon, dire qu'un langage est moche, quel qu'il soit c'est un peu débile ...
    Le langage est secondaire dans tout les cas.

    Il n'est là que pour permettre d'atteindre un but précis : donner vie à une idée.
    Celui qui se masturbe sur le langage est clairement à des années lumières d'avoir compris le boulot de développeur.

    Même si il est évident que certains sont plus adapté à des contextes et que donc, la règle numéro une dans ce métier c'est "ça dépend", même là, s'attacher à ça n'est pas se concentrer sur les bonnes choses.

    Les seuls à être convaincu de l'inverse de ce que je viens d'écrire, ce sont les mecs formés à l'arrache en six mois, ultra spécialisé qui ne connaissent rien au code et qui se rendrons compte dans 5 ans qu'ils étaient sur la mauvaise route depuis le départ.

  13. #13
    Candidat au Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2016
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2016
    Messages : 1
    Points : 3
    Points
    3
    Par défaut Syntaxe moche ?
    Si tu code moche en C++ c’est ton problème 😬 pas les autres !

  14. #14
    Expert confirmé
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 524
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 524
    Points : 5 184
    Points
    5 184
    Par défaut
    Le binaire compilé en C++ s'exécute en seulement 1,8 fois moins de temps que le code javascript.
    Mon premier avis est que je doute que le code C++ soit correctement écrit.
    En plus, comparer des temps d'exécution de cet ordre (moins d'une seconde) manque de précision.

    Dire que C++ a une syntaxe moche est plus que ridicule vu que la beauté c'est subjectif, et la beauté d'un code c'est... encore plus subjectif.
    Perso je préfère le C# mais jamais je n'irai dire que c'est plus beau ou moins moche qu'un autre langage.
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  15. #15
    Membre éclairé
    Homme Profil pro
    retraité
    Inscrit en
    Avril 2009
    Messages
    374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 91
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : retraité
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Avril 2009
    Messages : 374
    Points : 783
    Points
    783
    Par défaut C'est tout
    3 fois plus rapide !
    Mazette, il faut y croire, ma conviction est que ...

  16. #16
    Membre régulier Avatar de vivid
    Profil pro
    Inscrit en
    Février 2006
    Messages
    166
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 166
    Points : 119
    Points
    119
    Par défaut
    X3 fois plus rapide, c'est reconnaitre que la version précédente a été conçue avec les pieds ! ils font la promotion de leur incompétence ?!!

  17. #17
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 798
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 798
    Points : 7 066
    Points
    7 066
    Par défaut
    Bonjour,

    Dire qu'un langage est moche est très souvent subjectif et un avis de ce type ne concerne que soit. On lui demande le sien, il le donne... ce n'est pas pour ça que le contredire lui fera changer d'avis sur le C++ ou tout ceux qui sont d'accord avec lui.

    La version 3.11 est sans doute améliorée, ce n'est pas pour autant que j'ai choisi ce langage, et ce n'est pas non plus pour cela que des développeurs se mettront à apprendre ce langage.

    Même si c'est plus rapide, ça ne le sera pas suffisamment face à des langages compilés et autant dire que c'est souvent à cette comparaison (langages interprétés - compilés) que l'on fait référence.

    Par contre cette amélioration peut être intéressante et faire la différence sur des langages comme ruby, R et surtout celui qui commence à faire de l'ombre... julia.

    julia étant connu pour être bien plus performant et spécialisé pour des travaux scientifiques, on peut être amené à choisir l'un ou l'autre, et cette version 3.11 équilibre les forces côté performances.
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  18. #18
    Membre éprouvé Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    934
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 934
    Points : 1 274
    Points
    1 274
    Par défaut
    La performance des langages n'est pas seulement accessoire

    Un bon langage qui permet de faire plus facilement du code compact et rapide permet :
    - d'économiser de l'énergie
    - d'utiliser un système avec moins de RAM, moins de ROM et un CPU plus lent ce qui éviter de remplacer son matériel

    Un langage à la fois lent et populaire est une catastrophe pour la planète et nos portemonnaies.

    Bien sûr, il y a le rôle du programmeur qui doit optimiser son code.

    Exemple : sur Arduino, j'ai optimisé deux bibliothèques pour faire "rentrer" le code de mon projet dans les 32ko de rom (client TCP IP + écran LCD graphique + dalle tactile + capteurs). Non seulement ça marche mais en plus mes fonctions sont à la fois plus complète et sont 8 à 13 fois plus rapide que le code d'origine.
    Mais ça demandé pas mal de travail...
    ...et surtout mon code n'est plus "portables" sur les autres cartes à microcontrôleur
    ...normal, on ne peut pas tout avoir

    Quand on voit ce que demande en RAM et en CPU les versions actuelles de Word et Excel, alors qu'on ne fait pas grand chose de plus avec que les versions de 1997...

    Mon premier ordinateur était un Amiga 1200, CPU 68020 à 14Mhz, 2Mo de RAM, j'étais impressionné par ce qu'arrivait à en tirer les programmeurs de l'époque, notamment sur des jeux dignes de bornes d'arcade, des applications graphiques et musicales.

    S'agissant de la syntaxe et du confort, ça ne dépend pas que du langage mais aussi de l'IDE.
    Un langage "facile" peut être performant : si par exemple les premières versions de Visual Basic étaient lentes, la version VB.NET permet de faire du code aussi rapide qu'en C#
    Quand deux personnes échangent un euro, chacun repart avec un euro.
    Quand deux personnes échangent une idée, chacun repart avec deux idées.

Discussions similaires

  1. Réponses: 0
    Dernier message: 16/06/2021, 17h14
  2. Réponses: 0
    Dernier message: 07/10/2020, 20h29
  3. Kernel Linux : la version stable 2.6.38 est disponible
    Par Hinault Romaric dans le forum Linux
    Réponses: 0
    Dernier message: 16/03/2011, 13h10
  4. Linux : la version finale de Gentoo 2010 est disponible
    Par Katleen Erna dans le forum Actualités
    Réponses: 1
    Dernier message: 06/10/2009, 09h13
  5. Réponses: 56
    Dernier message: 03/09/2009, 01h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo