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 :

Rapidité de traitement .


Sujet :

Python

  1. #1
    Membre averti
    Inscrit en
    Mars 2010
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 46
    Par défaut Rapidité de traitement .
    Bjr,
    Le titre n'est pas très explicite, désolé mais je ne suis jamais bien inspiré pour trouver des titres claires ...

    J'aimerais savoir ce qui est plus rapide,
    Soit une suite de if, elif, else, ou un appel à de fonctions ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if 'TREE@TRUC' in sortie:
        commande
    elif 'TEXT@MACHIN' in sortie:
        commande
    elif .....
    ....
    ....
    Ou :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def TREE(arg):
        commande
    def TEXT(arg):
        commande
     
    fonction, arg = sortie.split('@')
    eval( "%s('%s')" % (fonction, arg) )
    Dans le même genre, j'ai une suite de if in or
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if ( 'pattern1' in ligne or 'pattern2' in ligne or 'pattern3' in ligne):
        commande obligatoire
        if  'pattern1' in ligne:
            commande
        elif 'pattern2' in ligne:
            commande
    Pour remplacer les if in or, j'ai utilisé une liste compréhension, mais c'est plus long que les if or. (normal, il matche chaque pattern pour le mettre dans la liste, avec les or, dès qu'il trouve, il arrête)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    defaut=[ 'pattern1', 'pattern2', 'pattern3']
    liste=[ i for i in defaut if i in ligne ]
    if liste:
        commande obligatoire
        if  'pattern1' in ligne:
            commande
        elif 'pattern2' in ligne:
            commande
    Je ne vois pas non plus comment me passer des if elif qui suivent, à moins de passer par une ER pour traiter la ligne et en récupérer ce qu'il faut pour lancer une fonction via eval, mais je pense que ca sera plus gourmand que des elif (enfin j'en sais rien, c'est bien pour ça que je pose cette question )

    Avec ma maigre expérience, j'ai remarqué qu'il été souvent plus rapide d'utiliser de if elif que des trucs plus complexes, certe le code est moins jolie, mais bon, c'est pas le but la beauté

    Merci d'avance à ceux qui vont éclairer ma lanterne.

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Par défaut
    Tes deux premiers morceaux de codes ne font pas exactement la même chose; il ne correspondront plus ou moins que si la chaine ne contient que 'TREE@TRUC' par exemple, mais dans ce cas au lieu de 'TREE@TRUC' in sortie tu pourrais écrire 'TREE@TRUC' == sortie qui sera déjà plus rapide.
    Le second code à l'avantage d'extraire l'argument ('TRUC') si tu en fais quelque chose dans la fonction.

    De façon générale, la séquence if/elif/../else sera plus rapide si le nombre de pattern n'est pas très élevé; s'il y en a vraiment beaucoup la solution avec eval sera plus rapide.

    Personnellement j'aurais plutôt écris quelque chose comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    class Traitement(object):
        def TREE(self, arg):
            ...
     
        def TEXT(self, arg):
            ...
     
    t = Traitement()
    fonction, arg = sortie.split('@')
    try:
        getattr(t, fonction)(arg)
    except AttributeError:
        ...
    On peut aussi utiliser des méthodes statiques s'il n'y pas besoin de conserver un état dans la classe Traitement, mais en général cela peut être utile.

    Pour le deuxième problème pourquoi ne pas écrire simplement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if  'pattern1' in ligne:
        commande obligatoire
        commande
    elif 'pattern2' in ligne:
        commande obligatoire
        commande
    "commande obligatoire" peut être un appel de fonction pour pas trop dupliquer de code.

  3. #3
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Dites... eval, c'est pas sérieux hein ?
    Parce que si dans le fichier il y a un os.rm ou des trucs du style... bon amusement.

  4. #4
    Membre Expert
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Par défaut
    Citation Envoyé par Antoine_935 Voir le message
    Dites... eval, c'est pas sérieux hein ?
    Parce que si dans le fichier il y a un os.rm ou des trucs du style... bon amusement.
    Ben non c'est pas sérieux. C'est juste pour s'amuser. J'adore m'amuser

  5. #5
    Membre averti
    Inscrit en
    Mars 2010
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 46
    Par défaut
    Personnellement j'aurais plutôt écris quelque chose comme:
    Je me demandais justement comment utilser getattr ... Je sais maintenant
    Il n'y aurait pas la même chose pour appeler une fonction dans sa class (j'ai cherché, mais pas trouver, à part passer par eval) ?

    Mais dans mon cas, les fonctions doivent être dans la même instance , je pourrais envoyer self en argument de class, mais j'ai peur que ca devienne illisible, déjà que dans cette classe j'utilise l'instance d'une autre classe, et c'est l'instance de cette dernière qui devra être utiliser, je sais pas si j'ai été clair
    En gros:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class père:
        gtk
        thread class enfant + self
    class enfant(threading.Thread):
        gui=self.père
        if True: modif gui.widget
    Pour modifier les widget, je m'amuse avec eval et exec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    arg='window.get_position()'
     position=eval('self.gui.%s' % arg)
    Donc si je veux 'délocaliser' , il faudra que j'embarque l'instance du père ! Je vais balader cette instance de class en class Je sais pas si c'est propre ?

    Arff, c'est histoire de class, d'instance, d'héritage & co, c'est assez dur à comprendre !

    Sinon, sur un chan IRC python-fr, on m'a conseillé de passer par des dictionnaires où j'y mets les fonctions à appeler selon la clés. C'est déjà plus propre et plus rapide qu'une suite de elif. (un petit mot au sujet du chan IRC, ils ont été sympa de m'aider, mais j'ai qd même eu droit à un RTFM au bout de 2 questions dont je n'avais pas bien saisi les réponses... Je comprends pas, si ca les fait chier de répondre, qu'est ce qu'ils foutent dans un chan d'entraide ??? Enfin, voilà pour mon coup de gueule, il fallait que sa sorte )

    "commande obligatoire" peut être un appel de fonction pour pas trop dupliquer de code.
    Je vais procéder comme ça, ca devrait fonctionner. Cette commande obligatoire référence les objets gtk, donc self, mais dans la même instance ce ne devrait pas poser de problèmes.

    Dites... eval, c'est pas sérieux hein ?
    Parce que si dans le fichier il y a un os.rm ou des trucs du style... bon amusement.
    C'est à dire ???

    En tout cas merci de votre aide

  6. #6
    Membre averti
    Inscrit en
    Mars 2010
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 46
    Par défaut
    Il n'y aurait pas la même chose pour appeler une fonction dans sa class (j'ai cherché, mais pas trouver, à part passer par eval) ?
    Des fois, moi .....
    J'ai pas essayé, mais en mettant self, ca devrait faire !

    Je passe en résolu, bien que j'ai pas eu d'avis d'experts sur l'utilisation de dictionnaire et le fait de balader une instance de class en class, ni sur le danger de eval ...!
    Mais bon, ça fonctionne bien comme ça .

    Merci de votre aide !

  7. #7
    Membre Expert
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Par défaut
    La solution du dictionnaire, c'est valable mais ce n'est pas très différent de la classe. Si un dictionnaire te suffit, alors une version avec des méthodes statiques suffirait aussi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Traitement(object):
        @staticmethod
        def TREE(arg):
            ...
     
        @staticmethod
        def TEXT(arg):
            ...
     
    fonction, arg = sortie.split('@')
    try:
        getattr(Traitement, fonction)(arg)
    except AttributeError:
        ...
    C'est vraiment très proche du dictionnaire. L'intérêt principal est qu'il ne faut pas déclarer les fonctions et construire le dictionnaire séparément, la déclaration de la classe s'en occupe. C'est plus dans le style orienté objet, alors que le dictionnaire est plus dans le style fonctionnel ou procédural.

    Le danger de eval et exec, c'est que si tu ne contrôles pas à 100% les chaînes de caractères qui sont passées, cela ouvre la porte à l'exécution de code arbitraire par un utilisateur mal intentionné (ou dans certains cas limites, simplement maladroit). Si la chaîne est dérivée d'une entrée de l'utilisateur, cela signifie de coûteuses validations, qui sont parfois (souvent?) compliquées à écrire (cela nécessite une bonne connaissance du langage d'écrire des validations correctes et exhaustives).

    Pour le fait de "balader une instance", je ne suis pas sûr de bien comprendre. Cela signifie passer l'instance en argument au constructeur lorsque tu instancies d'autres classes ? A priori, je ne vois pas de mal à cela.

  8. #8
    Membre averti
    Inscrit en
    Mars 2010
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 46
    Par défaut
    Citation Envoyé par dividee Voir le message
    La solution du dictionnaire, c'est valable mais ce n'est pas très différent de la classe. Si un dictionnaire te suffit, alors une version avec des méthodes statiques suffirait aussi:
    Je vais peut être passé pour un imbécile, mais j'ai tjrs pas compris le principe des staticmethod, j'y ai pas non plus regardé de très très prêt (y a tellement chose à apprendre, qd je coince sur un truc, j'y reviens plus tard ...Pourtant, à ce sujet, j'ai gratter un peu qd même, mais c'est tjrs obscur).
    Je vais pas te demander d'explication, car le sujet m'a l'air un peu complexe (quoique, si tu as du temps à perdre )

    Finalement j'utilise getattr, pas de dico à créer (c'est plus propre)
    avant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    dic_cmd={'SET':self.SET, 'GET':self.GET, 'EXIT':self.EXIT, 'COLOR':self.COLOR,
    			'TREE':self.TREE, 'TEXT':self.TEXT, 'STATUS':self.STATUS, 'IMG':self.IMG,
    			'GTKRC':self.GTKRC, 'NOTIFY':self.NOTIFY, 'ITER':self.ITER }
    cmd=sortie.split('@')[0]
    dic_cmd[cmd](sortie)
    Maintenant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cmd=sortie.split('@')[0]
    getattr(self, cmd)(sortie)
    C'est qd même mieux (merci !)


    Le danger de eval et exec, ......
    Dans mon cas, il n'y a pas trop de risque, donc ça ira bien comme ça !

    Pour le fait de "balader une instance", je ne suis pas sûr de bien comprendre. Cela signifie passer l'instance en argument au constructeur lorsque tu instancies d'autres classes ? A priori, je ne vois pas de mal à cela.
    Dsl, je n'emploi pas encore les termes exactes, ca viendra avec le temps je pense.
    Mais si tu ne trouve pas ça louche, tant mieux !

    Thx.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Lazarus] Rapidité de traitement d'image multi-plateforme
    Par Jack.R dans le forum Lazarus
    Réponses: 4
    Dernier message: 09/01/2014, 17h50
  2. l'unité de traitement (la rapidité de calcul)
    Par dominiqu dans le forum Assembleur
    Réponses: 11
    Dernier message: 20/02/2011, 13h08
  3. Rapidite de traitement par jointure ou par fonction
    Par garciajulien dans le forum Optimisations
    Réponses: 11
    Dernier message: 09/03/2010, 12h36
  4. De la rapidité du code
    Par jfloviou dans le forum Contribuez
    Réponses: 233
    Dernier message: 29/05/2009, 02h17
  5. rapidité de traitement en Dot net
    Par reverse_engineer dans le forum Débuter
    Réponses: 8
    Dernier message: 17/08/2008, 18h25

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