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{2.7,3.4} Amélioration des temps de traitement


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Âge : 70
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 34
    Par défaut [python{2.7,3.4} Amélioration des temps de traitement
    Bonjour,

    J'ai effectué un petit test comparatif sur un afficheur de news en mode console sur archlinux avec différents langages et outils dont vous trouverez le résultat ci-dessous.

    Il en ressort que le temps de chargement de python3 est relativement long, comparé aux autres environnements, notamment python2.7 .

    Dans l'attente de vos observations, suggestions, solutions et propositions.

    Code Résultats des benchs : 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
    26
    27
    28
    29
    30
    31
    Bench n°1: 100 lancement sur 1 rss local
    c module :      0.128
    c compilé jit : 0.28 
    lua :           0.36
    awk :           0.43
    sed :           0.58
    python2 :       0.95
    bash :          1.35
    python3 :       6.60
     
     
    Bench n°2: 1 lancement sur 300 rss concaténés
    c module :      0.065
    c compilé jit : 0.065
    python2 :       0.068
    python3 :       0.12
    awk :           0.18
    lua :           0.35
    sed :           0.58
    bash :          3.05
     
     
    Bench n°3: 100 lancements sur 300 rss concaténés
    c module :      5.82
    c compilé jit : 5.86 
    python2 :       6.25
    python3 :        12s
    awk :            18s
    lua :            33s
    sed :            58s
    bash :           73s (20 lancements)
    python3.4 : cat zz.txt | ./news3.py
    Code : 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
    26
    27
    28
    29
    30
    31
    32
    33
    #!/usr/bin/env python3
     
    import sys
     
    red  = "\033[31m"
    bleu = "\033[34m"
    gris = "\033[37m"
    defo = "\033[0m"
    buf = False
    l = []
     
    xml = sys.stdin.read().splitlines()
    for z in xml :
        z = z.lstrip()
        if z[0:7] == "<title>" : 
            if buf :
                l.append('\n')
                l.append(z[7:-8].replace('’', 'ʼ'))
            else :
                buf = True
                l.append("\n\t\t>> News Archlinux.fr <<\n")
        elif z[0:9] == "<pubDate>" : 
            l.append(' || ')
            l.append(bleu)
            l.append(z[14:-25])
            l.append('\n')
        elif z[0:15] == "<description><!" :
            l.append(gris)
            l.append(z[22:-17].replace('’', 'ʼ').replace('>', '>').replace('…', '...'))
            l.append(defo)
            l.append('\n')
     
    print(*l, sep='')
    python2.7 : cat zz.txt | ./news27.py
    Code : 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
    26
    27
    #!/usr/bin/env python2
    # -*- coding: utf-8 -*-
     
    import sys
     
    red  = "\033[31m"
    bleu = "\033[34m"
    gris = "\033[37m"
    defo = "\033[0m"
    buf = False
    buf2 = ''
     
    xml = sys.stdin.read().splitlines()
    for z in xml :
        z = z.lstrip()
        if z[0:7] == "<title>" : 
            if buf :
                print '\n{} || '.format(z[7:-8].replace('’', 'ʼ')),
            else :
                buf = True
                print "\n\t\t>> News Archlinux.fr <<"
        elif z[0:9] == "<pubDate>" : 
            print bleu + z[14:-25]
        elif z[0:15] == "<description><!" :
            print gris + z[22:-17].replace('’', 'ʼ').replace('>', '>').replace('…', '...') + defo
     
    print
    Fichiers attachés Fichiers attachés
    • Type de fichier : txt zz.txt (24,6 Ko, 66 affichages)

  2. #2
    Expert confirmé

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Par défaut
    Salut,

    Concernant ton code, il est optimisable.

    Par exemple, à quoi sert ".replace('>','>') ??? Tu perds deja du temps à cet endroit.

    Tu en perds également en accédant plusieurs fois à Z[0: x]. Deja la notation Z[: x] est plus pythonique, mais surtout, à chaque acces, tu change x, imposant une relecture. Lit Z[:7] et place le dans une variable avant ton if. Ensuite utilise ta variable dans les predicats. Oui pour les 2 et 3eme predicats, la comparaison n'est pas sur un mot complet mais une portion de mot, mais cela est bien suffisant je pense (au moins pour les deux premiers); et cela te permettra encore de gagner du temps d'exécution.

    Sinon concernant ta question première, il faut savoir que certaines fonctionnalités Python 3.X ont été réécrite et/ou fusionnées depuis la branche 2.X. Je pense que l'explication vient de là, car ce n'est pas la première fois que je constate ce genre de différence de temps d’exécution (dans les deux sens, je précise). C'est sur ce genre de petite chose qu'on tombe en essayant de migrer de la branche 2 à la branche 3.

    La solution utilisée généralement consiste à analyser le code section par section, afin d'isoler les différentes partie posant problème au niveau timing, et à réécrire, si possible, cette section.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Âge : 70
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 34
    Par défaut
    Bonsoir

    Citation Envoyé par deusyss Voir le message
    Par exemple, à quoi sert ".replace('>','>')
    Le gestionnaire a interprété la notation xml : replace('&#62 ;', '>')


    Citation Envoyé par deusyss Voir le message
    Tu en perds également en accédant plusieurs fois à Z[0: x]. Deja la notation Z[: x] est plus pythonique.
    et Z[: x] est 4% plus rapide en test unitaire.


    Citation Envoyé par deusyss Voir le message
    Concernant ton code, il est optimisable.
    Je l'ai optimisé suivant tes conseils, mais comme c'est un test comparatif, j'ai également optimisé les autres langages.
    Peu de changement dans le classement, python 3.4 est nettement plus lent (dans mes tests) que python 2.7.
    Les 2 versions de python sont plus lentes (dans mes tests) que perl et lua.
    Code Nouveau Résultat des benchs : : 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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    Bench n°1: 100 lancement sur 1 rss local avec affichage
    c module :      0.128
    c compilé jit : 0.28 
    lua :           0.32
    awk :           0.43
    perl :          0.50
    sed :           0.58
    python2 :       0.95
    bash :          1.35
    python3 :       1.60
     
     
    Bench n°2: 200 lancement sur 1 rss local        # time for i in {1..200};do cat zz|./script >/dev/null;done
    c module :      0.275
    lua :           0.46
    c compilé jit : 0.65 
    awk :           0.94
    perl :          0.95
    sed :           1.05
    python2 :       1.91
    bash :          1.53
    python3a :      3.24
    python3b :      3.25
     
     
    Bench n°3: 100 lancements sur 300 rss concaténés         # time for i in {1..100};do cat zy|./script >file;done
    c module :      1.23
    c compilé jit : 1.37 
    perl :          3.96
    python2 :       5.33
    lua :           6.65 26s
    python3a :      9.27 13s
    python3b :     10.23 13s
    awk :            13s
    sed :            49s
    bash :           56s (20 lancements)
     
     
    Bench n°4: 1 lancement sur 3000 rss concaténés           # sans affichage
    c module :      0.111
    c compilé jit : 0.120
    perl :          0.362 0.521
    python2 :       0.445 0.593
    lua :           0.661 2.532
    python3a :      0.768 1.056
    python3b :      0.870 1.116
    awk :           1.251
    sed :           4.918
     
    Python 2.7.8 (default, Jul  1 2014, 17:30:21) 
    [GCC 4.9.0 20140604 (prerelease)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import timeit
    >>> timeit.timeit("while i>0: i-=1","i=10**7")
    0.3921658992767334
    >>> timeit.timeit("while i>0: i-=1","i=10**7")
    0.3980870246887207
    >>> 
     
    Python 3.4.1 (default, May 19 2014, 17:23:49) 
    [GCC 4.9.0 20140507 (prerelease)] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import timeit
    >>> timeit.timeit("while i>0: i-=1","i=10**7")
    0.7147223350002605
    >>> timeit.timeit("while i>0: i-=1","i=10**7")
    0.71387163899999
    >>>
    Code python2 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #!/usr/bin/env python2         
    # -*- coding: utf-8 -*-        
     
    import sys
     
    for z in sys.stdin.read().splitlines() : 
        y = z[:5]                  
        if y == "<rss " :          
            print("\n\t\t>> News Archlinux.fr <<\n")
        elif y == "\t\t<ti" :      
            tit = z[9:-8].replace('’', 'ʼ') 
        elif y == "\t\t<pu" :      
            pub = z[16:-25]        
        elif y == "\t\t<de" :      
            print('{} || \033[34m{}\n\033[37m{}\033[0m\n'.format(tit, pub, z[24:-17].replace('’', 'ʼ').replace('>', '>').replace('…', '...')))
    Code python3a : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #!/usr/bin/env python          
     
    import sys
     
    for z in sys.stdin.read().splitlines() : 
        y = z[:5]                  
        if y == "<rss " :          
            print("\n\t\t>> News Archlinux.fr <<\n")
        elif y == "\t\t<ti" :      
            tit = z[9:-8].replace('&#8217 ;', 'ʼ')
        elif y == "\t\t<pu" :      
            pub = z[16:-25]        
        elif y == "\t\t<de" :      
            print('{} || \033[34m{}\n\033[37m{}\033[0m\n'.format(tit, pub, z[24:-17].replace('&#8217 ;', 'ʼ').replace('&#62 ;', '>').replace('&#8230 ;', '...')))
    Code python3b : 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
    26
    27
    #!/usr/bin/env python          
     
    import sys
     
    bleu = "\033[34m"              
    gris = "\033[37m"              
    defo = "\033[0m"               
    l = []
     
    for z in sys.stdin.read().splitlines() : 
        y = z[:5]
        if y == "<rss " :          
            print("\n\t\t>> News Archlinux.fr <<\n")
        elif y == "\t\t<ti" :      
            l.append(z[9:-8].replace('&#8217 ;', 'ʼ'))
        elif y == "\t\t<pu" :      
            l.append(' || ')       
            l.append(bleu)         
            l.append(z[16:-25])    
            l.append('\n')         
        elif y == "\t\t<de" :      
            l.append(gris)
            l.append(z[24:-17].replace('&#8217 ;', 'ʼ').replace('&#62 ;', '>').replace('&#8230 ;', '...'))
            l.append(defo)         
            l.append('\n\n')       
     
    print(*l, sep='')

  4. #4
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    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 : 4 062
    Par défaut
    python est un langage qui permet de comparer des algorithmes entre eux, de construire et de tester des implémentations. Optimiser quelques millièmes de secondes en cherchant à corriger une implantation CPython est totalement inutile, il y a des mecs bien plus calés que nous pour trouver et modifier tout cela.
    Si ça n'a pas été fait, c'est que ça n'en valait pas le coup.

    Si vraiment tu veux gagner du temps de réponse, maintenant que ton algorithme est construit, tu peux le faire en C, C++, voir cython par exemple (il y en a d'autres évidemment plus performant que python).

    Personnellement j'aime bien cython, boost et de plus en plus lua.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Âge : 70
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 34
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    python est un langage qui permet de comparer des algorithmes entre eux, de construire et de tester des implémentations. Optimiser quelques millièmes de secondes en cherchant à corriger une implantation CPython est totalement inutile, il y a des mecs bien plus calés que nous pour trouver et modifier tout cela.
    Si ça n'a pas été fait, c'est que ça n'en valait pas le coup.

    Si vraiment tu veux gagner du temps de réponse, maintenant que ton algorithme est construit, tu peux le faire en C, C++, voir cython par exemple (il y en a d'autres évidemment plus performant que python).

    Personnellement j'aime bien cython, boost et de plus en plus lua.
    J'ai du mal m'exprimer:
    Comparer les temps d'exécution de C et python ne me parait pas présenter beaucoup d'intérêt. Pas besoin de test, pour savoir lequel est le plus rapide.
    En revanche comparer les temps d'exécution de Python2, Python3, Perl, Lua me parait intéressant.

    Dans les tests que j'ai faits (petit programme de rien du tout et tests unitaires), Python2 est toujours plus rapide que Python3.
    Personnellement, je trouve ça décevant.

    Code C : 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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    #!/usr/bin/tcc -run 
     
    #include <stdio.h>
    #include <string.h>
     
    #define MAX_LINE_SIZE   1024
    #define BLEU            "\e[34m"
    #define GRIS            "\e[37m"
    #define DEFO            "\e[0m"
     
    void replace(char *z, char *cible, char rep ) { 
         char buf[MAX_LINE_SIZE];
         char *y; 
     
         while ( y = strstr(z, cible) ) { 
              y[0] = rep;
              strcpy(buf, y+strlen(cible));
              strcpy(y+1, buf);
         }   
    }
     
    int main() {
         char line[MAX_LINE_SIZE];
         char y[6]; y[5] = '\0';
         char *z; 
         int on_one = 1;
     
         while ( fgets(line, MAX_LINE_SIZE, stdin) ) { 
            memcpy(y, line, 5); 
            if ( strcmp(y, "<rss ") == 0 ) { 
                printf("\n\t\t>> News Archlinux.fr <<\n\n");
            }   
            else if ( strcmp(y, "\t\t<ti") == 0 ) { 
                line[strlen(line)-9] = '\0';
                replace(line, "&#8217 ;", '\'' ); 
                printf("%s", line+9);
            }   
            else if ( strcmp(y, "\t\t<pu") == 0 ) { 
                line[strlen(line)-26] = '\0';
                printf(" || %s%s%s\n", BLEU, line+16, DEFO);
            }   
            else if ( strcmp(y, "\t\t<de") == 0 ) { 
                line[strlen(line)-27] = '\0';
                replace(line, "&#8217 ;", '\'' ); 
                replace(line, "&#62 ;", '>' ); 
                printf("%s%s[...]%s\n\n", GRIS, line+24, DEFO);
            }   
         }   
         return 0;
    }

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    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 741
    Par défaut
    Salut,

    Citation Envoyé par avi3000 Voir le message
    En revanche comparer les temps d'exécution de Python2, Python3, Perl, Lua me parait intéressant.

    Dans les tests que j'ai fait (petit programme de rien du tout et tests unitaires), Python2 est toujours plus rapide que Python3.
    Personnellement, je trouve ça décevant.
    Si vous vous contentez de comparer un bout de code vous allez avoir une vue limitée aux fonctions utilisées par ce code de l'implémentation "en dessous".

    Pour benchmarker, il faudrait élargir l'ensemble des fonctions testées.
    Le résultat sera plus dispersé: des "plus" dans certains cas et des "moins" dans d'autres.
    Faites quelques recherches sur Google pour récupérer les résultats de ces benchmarks: çà ne s'organise pas sur un coin de table, assurez vous de leur sérieux!

    Si vos tests durent un pouième mais nécessitent de charger l'interpréteur Python, vous avez déjà une forte variabilité due aux chargements de Python et de ses bibliothèques qui biaisera les résultats sans être nécessairement significatifs.

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

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Âge : 70
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 34
    Par défaut
    Bonjour,

    Que python3 soit plus efficace pour faire des choses compliquées, c'est parfait.

    Mais est-il normal qu'une simple boucle while soit quasiment 2 fois plus rapide en python2?

    Etant un esprit simple, programmant simplement des applications simples, je ne voit pas trop le progrès.
    Je suis certainement trop cartésien.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Python 2.7.8 (default, Jul  1 2014, 17:30:21) 
    [GCC 4.9.0 20140604 (prerelease)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import timeit
    >>> timeit.timeit("while i>0: i-=1","i=10**7")
    0.3921658992767334
    >>> timeit.timeit("while i>0: i-=1","i=10**7")
    0.3980870246887207
    >>>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Python 3.4.1 (default, May 19 2014, 17:23:49) 
    [GCC 4.9.0 20140507 (prerelease)] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import timeit
    >>> timeit.timeit("while i>0: i-=1","i=10**7")
    0.7147223350002605
    >>> timeit.timeit("while i>0: i-=1","i=10**7")
    0.71387163899999
    >>>

    Citation Envoyé par wiztricks
    Si vos tests durent un pouième mais nécessitent de charger l'interpréteur Python
    Ce qui explique mes tests avec 1, 100, 200 ou 300 lancements.
    Comparer les temps de chargement d'un interpréteur ou d'un compilateur en ligne, est peut-être une imbécilité, mais j'ai la faiblesse de m'y intéresser.

Discussions similaires

  1. Réponses: 9
    Dernier message: 01/10/2012, 16h04
  2. Améliorer le temps d'exécution des boucles imbriquées
    Par alexmam15 dans le forum Débuter
    Réponses: 14
    Dernier message: 22/02/2011, 15h25
  3. Amélioration du temps de calcul pour creer des figures
    Par comoliv02 dans le forum MATLAB
    Réponses: 2
    Dernier message: 17/10/2007, 11h23
  4. CpteDom - amélioration des temps de réponse
    Par Domi2 dans le forum Access
    Réponses: 2
    Dernier message: 25/10/2006, 14h29

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