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 :

Comment obtenir la représentation hexadecimale d'une chaine de caractères


Sujet :

Python

  1. #21
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 34
    Points : 13
    Points
    13
    Par défaut
    Python3 vs Python2.
    c'est win2000 + python 2.7 au bureau, et ubuntu 10.04 + python 2.6 à la maison.
    pour python 3, je vais attendre un peu.

    >> Reste l'option du module C si c'est trop lent.
    à +6 minutes par nuit, je peux faire l'impasse sur le C.

  2. #22
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 046
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 046
    Points : 1 376
    Points
    1 376
    Par défaut
    je ne sais pas si ça a été dejà posté ... la flemme de lire ^^
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ma_chaine = 'azerty'
    ''.join(map(hex,bytearray(ma_chaine))).replace('0x','')
    ==> '617a65727479'

  3. #23
    Membre expérimenté
    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
    Points : 1 384
    Points
    1 384
    Par défaut
    Je n'ai pas lu toute la discussion, juste les derniers posts, mais quand j'ai un tas de strings à concaténer, je les mets dans une liste ou et je fais un ''.join dessus à la fin. C'est simple et efficace.
    Dans ce cas-ci on dirait qu'on peut même faire '$'.join(...)

    [EDIT] Oops j'avais pas vu qu'il y avait une seconde page ^^. Déjà proposé par josmiley. Enfin on parle peut-être pas tout à fait de la même chose.

  4. #24
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Au lieu de
    "".join( [x for x in .....] )
    on peut écrire
    "".join( x for x in ........ )





    À la place de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    lambda nb:''.join([hex(ord(i)).strip('0x').rjust(2, '0') for i in nb])
    il y avait aussi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    lambda nb:''.join([hex(ord(i))[2:].zfill(2) for i in nb])






    La fonction comp3() dans le message #4 arrive comme un cheveu dans la soupe: on se demande pourquoi comp3( chr(0x00) ) donne ’00’ et pourquoi comp3( chr(0x3d) ) donne un signe à l’ensemble.
    C’est ton algo qui est comme ça, mais ça surprend.










    time.clock()

    On Unix, return the current processor time as a floating point number expressed in seconds. The precision, and in fact the very definition of the meaning of "processor time", depends on that of the C function of the same name, but in any case, this is the function to use for benchmarking Python or timing algorithms.
    On Windows, this function returns wall-clock seconds elapsed since the first call to this function, as a floating point number, based on the Win32 function QueryPerformanceCounter(). The resolution is typically better than one microsecond.

    http://docs.python.org/library/time.html








    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    import binascii
     
    while 1:
         ...............
     
         inHex = binascii.hexlify(inChr)
    À chaque tour de l’itération , l’interpréteur est obligé d’aller chercher dans binsacii la fonction hexlify() . C’est perdre du temps pour rien.

    Importer la fonction hexlify() dans l’espace de noms global avec from binascci import hexlify
    la rend directement disponible et élimine une perte de temps répétitive.







    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    print a.encode("hex")
    '6d657373616765'
    Bien vu !
    Je ne connaissais pas cette utilisation des fonctions encode() et decode() avec ce codec et ses camarades.
    Dommage que ce soit plus lent.









    out = ''
    out += trt_pack(inHex[0:6]) #iavo
    out += "$"
    out += trt_date(inHex[6:15]) #dins
    out += "$"
    out += inChr[8:9] #cins
    out += "$"

    ....................

    Avec autant de concaténations, pas étonnant que ça prenne beaucoup de temps.
    C’est sûr !!

    Pour concaténer, il y a deux méthodes lentes:
    += et formatage avec %,
    et deux méthodes rapides:
    + et join()





    Et il y a d’autre choses étonnantes.
    "".ljust(10, ' ') dans la fonction trt_date(d) est assez cocasse.



    La fonction trt_packdec() créée pour deux utilisations seulement
    trt_packdec(inHex[66:74], 4)
    et trt_packdec(inHex[74:82], 2)
    dont on s’aperçoit qu’elles sont simplifiables ,
    est aussi un marteau-piqueur pour écraser deux noisettes. Un appel de fonction est coûteux en temps, celle -ci juste pour faire du calcul d’indice.
    J’ai donc simplifié.




    J’ai aussi remplacé la fonction trt_pack() par un dictionnaire qui donne le signe en un clin d’œil.





    Il est plus rapide de travailler en mémoire et d'écrire les fichiers par bloc.
    Je suis d’accord. Donc, application: lecture du fichier 'packed_file' par gros morceaux de 4700 caractères et plus, traités en entier avant qu’il y ait écriture.
    4700 est une valeur minime. En fonction des possibilités de la machine sur laquelle ça tournera, ce nombre pourra être augmenté. Il faudra rechercher la valeur optimale.







    Enfin, comme le temps d’exécution dépend fortement de l’algorithme plutôt que des astuces trouvées dans la manière d’écrire un code , il faut à mon avis modifier la construction de out en évitant des opérations inutiles de concaténation.


    J’ai un peu modifié ton code, avi3000, pour mener des tests (fonction clock, nombre nn de z écrits...) mais pas son algorithme.

    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
    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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    #!/usr/bin/env python
    # -*- coding:UTF-8 -*-
    """ conversion de la table ACT """
     
    from time import clock
    import binascii
     
    def trt_act():
           """ création du fichier étendu 200 000 records, 20 Mo """
     
           i = 0
           inFile = open('packed_file', 'r')
           outFile = open('mis_a_plat', 'w')
     
           while 1:
                  inChr = inFile.read(47)
                  if inChr == '' :            break
                  inHex = binascii.hexlify(inChr)
     
                  out = ''
                  out += trt_pack(inHex[0:6])               #iavo
                  out += "$"
                  out += trt_date(inHex[6:15])              #dins
                  out += "$"
                  out += inChr[8:9]                                #cins
                  out += "$"
                  out += trt_date(inHex[18:27])             #dces
                  out += "$"
                  out += inChr[14:15]                              #cces
                  out += "$"
                  out += trt_pack(inHex[30:34])             #iban
                  out += "$"
                  out += inChr[17:20]                              #natv
                  out += "$"
                  out += inChr[20:21]                              #catv
                  out += "$"
                  out += trt_pack(inHex[42:48])             #istr
                  out += "$"
                  out += trt_pack(inHex[48:52])             #qann
                  out += "$"
                  out += trt_pack(inHex[52:56])             #qmoi
                  out += "$"
                  out += trt_pack(inHex[56:60])             #qjou
                  out += "$"
                  out += trt_pack(inHex[60:66])             #cpay
                  out += "$"
                  out += trt_packdec(inHex[66:74], 4)       #qexe
                  out += "$"
                  out += trt_packdec(inHex[74:82], 2)       #qex2
                  out += "$"
                  out += inChr[41:42]                              #ccer
                  out += "$"
                  out += trt_date(inHex[84:93])             #dmaj
                  outFile.write(out + '\n')
     
           inFile.close(), outFile.close();
     
    def trt_pack(s):
           """ traitement des entiers """
           if s[-1] == 'f' :                  
                  return '+' + s[:-1]
           elif s[-1] == 'd'  : 
                  return '-' + s[:-1]
           else :
                  return '%' + s[:-1]  
     
    def trt_packdec(s, d):
           """ traitement des nombres décimaux """
     
           if s[-1] == 'f' :                  
                  sign = '+'
           elif [-1] == 'd'  :  
                  sign = '-'
           else :
                  sign = '%'
           return sign + s[:len(s)-d-1] + ',' + s[len(s)-d-1:-1]
     
    def trt_date(d):
           """ traitement des dates """
     
           aaaa = d[1:5]
           mm = d[5:7]
           jj = d[7:]
     
           if aaaa == '0000' :                
                  return ''.ljust(10, ' ')
           elif mm == '00' or jj == '00' :    
                  return '01/01/' + aaaa
           else :
                  return jj + '/' + mm + '/' + aaaa  
     
    def create_act(nn):
           """ création du fichier de test 200 000 records, 9 Mo """
     
           z = chr(0x00) + chr(0x00) + chr(0x1f)                                               #iavo
           z += chr(0x01) + chr(0x94) + chr(0x60) + chr(0x41)  + chr(0x2f)       #dins                                            
           z += 'S'                                                                                                 #cins
           z += chr(0x00) + chr(0x00) + chr(0x00) + chr(0x00)  + chr(0x0f)       #dces                                            
           z += ' '                                                                                                 #cces
           z += chr(0x10) + chr(0x5f)                                                                 #iban
           z += '511'                                                                                               #natv
           z += '5'                                                                                                 #catv
           z += chr(0x29) + chr(0x00) + chr(0x3f)                                              #istr
           z += chr(0x03) + chr(0x8f)                                                                 #qann
           z += chr(0x02) + chr(0x6f)                                                                 #qmoi
           z += chr(0x01) + chr(0x2f)                                                                 #qjou
           z += chr(0x10) + chr(0x23) + chr(0x1f)                                              #fill
           z += chr(0x03) + chr(0x82) + chr(0x61) + chr(0x2f)                           #qexe
           z += chr(0x03) + chr(0x72) + chr(0x61) + chr(0x2f)                           #qex2
           z += 'C'                                                                                                 #ccer
           z += chr(0x02) + chr(0x00) + chr(0x31) + chr(0x22)  + chr(0x5f)       #dmaj                                            
     
           i = 0
           outFile = open('packed_file', 'w')
           while i < nn:
                  outFile.write(z)
                  i += 1
           outFile.close()
     
           return len(z)
     
    #=============
    if __name__ == "__main__":
           import os 
           os.system('clear')
           #for nn in (1000,2000,4000,8000,16000,32000,100000):
           for nn in (200000,):
                   print 'nn = '+str(nn)+ ' code avi3000'
                   licreate,liunpack = [],[]
                   for fois in xrange(3):
                          t1 = clock()
                          lenz = create_act(nn)
                          dt1 = clock() - t1
                          licreate.append(dt1)
                   min_create = min(licreate)
                   for u in xrange(20):
                           t1 = clock()
                           trt_act()
                           dt2 = clock() - t1
                           liunpack.append(dt2)
                           print str(lenz)+'  create (minimum) : ' + str(min_create)[0:8]+\
                                 '    unpack : ' + str(dt2)[0:8]+\
                                 '    ratio : '+str(dt2/min_create)[0:5]
                           #print 'ghgh' + 'éèàù'
                   print 24*' '+'MINIMUM ~~ unpack = '+ str(min(liunpack))[0:8]+\
                         ' ~~ ratio = '+ str(min(liunpack)/min_create)[0:5]+'\n'

    J’avais d’abord fait un code sans lecture par morceaux.

    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
    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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    #!/usr/bin/env python
    # -*- coding:UTF-8 -*-
    """ conversion de la table ACT """
     
    from time import clock
    from binascii import hexlify
    from os.path import getsize
     
     
    def create_act(nn):
        """ création du fichier de test 200 000 records, 9 Mo """
     
        z = (chr(0x00) , chr(0x00) , chr(0x1f) ,
             chr(0x01) , chr(0x94) , chr(0x60) , chr(0x41)  , chr(0x2f) ,   #dins
             'S' ,
             chr(0x00) , chr(0x00) , chr(0x00) , chr(0x00)  , chr(0x0f) ,   #dces
             ' ' ,
             chr(0x10) , chr(0x5f) ,                                        #iban
             '5115' ,
             chr(0x29) , chr(0x00) , chr(0x3f) ,	                        #istr
             chr(0x03) , chr(0x8f) ,                                        #qann
             chr(0x02) , chr(0x6f) ,                                        #qmoi
             chr(0x01) , chr(0x2f) ,	                                #qjou
             chr(0x10) , chr(0x23) , chr(0x1f) ,		                #fill
             chr(0x03) , chr(0x82) , chr(0x61) , chr(0x2f) ,	        #qexe
             chr(0x03) , chr(0x72) , chr(0x61) , chr(0x2f) ,	        #qex2
             'C' ,
             chr(0x02) , chr(0x00) , chr(0x31) , chr(0x22)  , chr(0x5f))    #dmaj
        z = ''.join(z)
     
        with open('packed_file47', 'w') as outFile:
            for i in xrange(nn):
                outFile.write(z)
     
        return len(z)
     
     
    def trt_act():
        """ création du fichier étendu 200 000 records, 20 Mo """
     
        pack = {}.fromkeys('0123456789abc','%')
        pack['d'] = '-'
        pack['f'] = '+'
     
        def trt_date(d):
            """ traitement des dates """
            if d[1:5] == '0000' :
                return '          '
            elif d[5:7] == '00' or d[7:] == '00' :
                return '01/01/' + d[1:5]
            else :
                return d[7:] + '/' + d[5:7] + '/' + d[1:5]
     
     
        with open('packed_file47', 'r') as inFile, open('mis_a_plat47', 'w') as outFile:
            inChr = inFile.read(47)
            while len(inChr):
                inHex = hexlify(inChr)
                out = (pack[inHex[5]] + inHex[0:5],     #iavo
                       trt_date(inHex[6:15]),           #dins
                       inChr[8],                        #cins
                       trt_date(inHex[18:27]),          #dces
                       inChr[14],                       #cces
                       pack[inHex[33]] + inHex[30:33],  #iban
                       inChr[17:20],                    #natv
                       inChr[20:21],                    #catv
                       pack[inHex[47]] + inHex[42:47],  #istr
                       pack[inHex[51]] + inHex[48:51],  #qann
                       pack[inHex[55]] + inHex[52:55],  #qmoi
                       pack[inHex[59]] + inHex[56:59],  #qjou
                       pack[inHex[65]] + inHex[60:65],  #cpay
                       pack[inHex[73]] + inHex[66:69] + ',' + inHex[69:73],    #qexe
                       pack[inHex[81]] + inHex[74:79] + ',' + inHex[79:81],    #qex2
                       inChr[41],                       #ccer
                       trt_date(inHex[84:93]) + '\n')   #dmaj
     
                outFile.write('$'.join(out))
                inChr = inFile.read(47)
     
     
    #=============
    if __name__ == "__main__":
        import os 
        os.system('clear')
        #for nn in (1000,2000,4000,8000,16000,32000,100000):
        for nn in (200000,):
            print 'nn = ' + str(nn) + '   lecture par 47 octets'
            licreate = []
            liunpack = []
            for fois in xrange(3):
                t0 = clock()
                lenz = create_act(nn)
                dt1 = clock() - t0
                licreate.append(dt1)
            min_create = min(licreate)
            for u in xrange(20):
                t0 = clock()
                trt_act()
                dt2 = clock() - t0
                liunpack.append(dt2)
                print str(lenz)+'  create (minimum) : ' + str(min_create)[0:8]+\
                      '    unpack : ' + str(dt2)[0:8]+\
                      '    ratio = '+str(dt2/min_create)[0:5]
                #print 'ghgh' + 'éèàù'
            print 24*' '+'MINIMUM ~~ unpack = '+ str(min(liunpack))[0:8]+\
                  ' ~~ ratio = '+ str(min(liunpack)/min_create)[0:5]+'\n'


    Et finalement j’ai aussi réécrit le code pour faire la lecture de ’packed_file’ par morceaux.

    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
    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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    #!/usr/bin/env python
    # -*- coding:UTF-8 -*-
    """ conversion de la table ACT """
     
    from time import clock
    from binascii import hexlify
    from os.path import getsize
     
     
    def trt_act(taille_chunk):
        """ création du fichier étendu 200 000 records, 20 Mo """
     
        pack = {}.fromkeys('0123456789abc','%')
        pack['d'] = '-'
        pack['f'] = '+'
     
        def trt_date(d):
            """ traitement des dates """
            if d[1:5] == '0000' :
                return '          '
            elif d[5:7] == '00' or d[7:] == '00' :
                return '01/01/' + d[1:5]
            else :
                return d[7:] + '/' + d[5:7] + '/' + d[1:5]
     
        def outing(inChunk):
            for k in xrange(0,len(inChunk), 47):
                inHex = hexlify(inChunk[k:k+48])
                yield '$'.join((pack[inHex[5]] + inHex[0:5],    #iavo
                                trt_date(inHex[6:15]),          #dins
                                inChunk[k+8],                   #cins
                                trt_date(inHex[18:27]),         #dces
                                inChunk[k+14],                  #cces
                                pack[inHex[33]] + inHex[30:33], #iban
                                inChunk[k+17:k+20],             #natv
                                inChunk[k+20:k+21],             #catv
                                pack[inHex[47]] + inHex[42:47], #istr
                                pack[inHex[51]] + inHex[48:51], #qann
                                pack[inHex[55]] + inHex[52:55], #qmoi
                                pack[inHex[59]] + inHex[56:59], #qjou
                                pack[inHex[65]] + inHex[60:65], #cpay
                                pack[inHex[73]] + inHex[66:69] + ',' + inHex[69:73],    #qexe
                                pack[inHex[81]] + inHex[74:79] + ',' + inHex[79:81],    #qex2
                                inChunk[k+41],                  #ccer
                                trt_date(inHex[84:93]) + '\n')) #dmaj
     
        with open('packed_file'+str(taille_chunk), 'r') as inFile:
            with open('mis_a_plat'+str(taille_chunk), 'w') as outFile:
                inChunk = inFile.read(taille_chunk)
                while len(inChunk):
                    outFile.write(''.join(line for line in outing(inChunk)))
                    inChunk = inFile.read(taille_chunk)
     
     
    def create_act(nn):
        """ création du fichier de test nn records, ~9 Mo si nn = 200000"""
     
        z = (chr(0x00) , chr(0x00) , chr(0x1f) ,
             chr(0x01) , chr(0x94) , chr(0x60) , chr(0x41)  , chr(0x2f) ,   #dins
             'S' ,
             chr(0x00) , chr(0x00) , chr(0x00) , chr(0x00)  , chr(0x0f) ,   #dces
             ' ' ,
             chr(0x10) , chr(0x5f) ,                                        #iban
             '5115' ,
             chr(0x29) , chr(0x00) , chr(0x3f) ,	                        #istr
             chr(0x03) , chr(0x8f) ,                                        #qann
             chr(0x02) , chr(0x6f) ,                                        #qmoi
             chr(0x01) , chr(0x2f) ,	                                #qjou
             chr(0x10) , chr(0x23) , chr(0x1f) ,		                #fill
             chr(0x03) , chr(0x82) , chr(0x61) , chr(0x2f) ,	        #qexe
             chr(0x03) , chr(0x72) , chr(0x61) , chr(0x2f) ,	        #qex2
             'C' ,
             chr(0x02) , chr(0x00) , chr(0x31) , chr(0x22)  , chr(0x5f))    #dmaj
        z = ''.join(z)
     
        with open('packed_file'+str(taille_chunk), 'w') as outFile:
            for i in xrange(nn):
                outFile.write(z)
     
        return len(z)
     
     
    #=============
    if __name__ == "__main__":
        import os 
        os.system('clear')
        taille_chunk = 940000
        #for nn in (1000,2000,4000,8000,16000,32000,100000):
        for nn in (200000,):
            print 'nn = ' + str(nn) + '   lecture par morceaux de '+str(taille_chunk)+' octets'
            licreate,liunpack = [],[]
            for fois in xrange(3):
                t0 = clock()
                lenz = create_act(nn)
                dt1 = clock() - t0
                licreate.append(dt1)
            min_create = min(licreate)
            for u in xrange(20):
                t0 = clock()
                trt_act(taille_chunk)
                dt2 = clock() - t0
                liunpack.append(dt2)
                print str(lenz)+'  create (minimum) : ' + str(min_create)[0:8]+\
                      '    unpack : ' + str(dt2)[0:8]+\
                      '    ratio : '+str(dt2/min_create)[0:5]
                #print 'ghgh' + 'éèàù'
            print 24*' '+'MINIMUM ~~ unpack = '+ str(min(liunpack))[0:8]+\
                  ' ~~ ratio = '+ str(min(liunpack)/min_create)[0:5]+'\n'


    ----------------------------------------------


    J’ai mené des tests avec
    for nn in (1000,2000,4000,8000,16000,32000,100000):
    mais les résultats sont assez surprenants.

    nn est le nombre de z écrits dans ’packed_file’ dans la partie create()
    Je pensais que le ratio temps d’exécution de unpack/temps d’exécution de create évoluerait d’une manière continue avec nn, plutôt à la hausse, et que cette variation serait différente selon le code.

    Mais pour un même code, il y a une variation bizarre du ratio, sans liaison avec la valeur de nn, mais identique avec les 3 programmes ! : le ratio augmente d’environ 60 % de nn = 1000 à nn = 2000 et 4000, puis il augmente un peu pour nn = 8000, 16000, 32000, puis pouf ! il retombe fortement pour nn = 100000, à une valeur qui est même en dessous de la valeur du ratio pour nn = 1000 !!
    Je n’y comprends rien. Mais je pense que ce n’est pas le plus intéressant.


    -----------------------------------------------------




    Je me suis donc intéressé exclusivement aux temps de unpack pour nn = 200000 que j'ai comparé entre eux.

    J'ai fait en sorte de trouver d'abord le temps minimal de création de 'packed_file' (il devrait logiquement être assez constant mais ce n’est pas tout à fait le cas) et j'ai fait répéter plusieurs fois l'exécution de trt_act() pour extraire le temps minimal parmi les divers essais.

    J'ai comparé les temps minimaux obtenus sur les 3 programmes car ils sont plus significatifs des performances les meilleures que peuvent avoir des programmes quand ils ne sont pas gênés par des événements ordinateurs parasitant le CPU.

    PGavi :
    celui du message #11 avec les fonctions trt_date(d) , trt_packdec(s, d) , trt_pack(s) , et des concaténations +=

    PGey1 :
    avec lecture de ’'packed_file47' par 47 octets, tuple out et outFile.write('$'.join(out)) , dictionnaire pack à la place de la fonction trt_pack(s) , disparition de la fonction trt_packdec(s, d)

    PGey2 :
    avec lecture de ’'packed_file4700' par morceaux inChunk de 4700,47000,94000 octets, fonction génératrice renvoyant un ’$’.join(out) , dans out utilisation de pack au lieu de trt_pack(s) et plus de trt_packdec(s, d) comme dans PGey1.


    NB: j’ai vérifié mes codes PGey en comparant les fichiers ’mis_a_plat’ obtenus par eux avec le fichier obtenu par ton code PGavi. C’est identique.




    Résultats, pour nn = 200000

    PGey1 / PGavi = 61,9 %
    PGey2 / PGavi = 58,2 % avec taille_chunk = 4700
    PGey2 / PGavi = 55,6 % avec taille_chunk = 47000
    PGey2 / PGavi = 53,3 % avec taille_chunk = 94000


    Mon ordi était très lent, les valeurs absolues n’auraient aucun intérêt.
    Dîtes moi si vous retrouvez la même baisse de temps d’exécution sur vos machines, svp.


    Je pensais que la différence serait plus importante de PGey1 à PGey2, c’est à dire que la lecture par morceaux (donc et surtout écriture par grands morceaux aussi) apporterait une augmentation de la rapidité déjà constatée avec PGey1 par rapport à PGavi.
    Mais la lecture et l’écriture par morceaux n’a pas tant d’influence que ça.



    -----------------------------


    Je pense qu'on pourrait encore creuser les choses pour trouver des optimisatiions supplémentaires.

    Il y en a une notamment dans la fonction trt_date(d):
    si les fichiers sont tels qu’on y rencontre le plus souvent des aaaa == '0000' ,
    la place de if aaaa == '0000' : est alors bien en premier.
    Mais si les dates sont le plus souvent normales, il faut mettre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if aaaa!='0000' and mm!='00' and jj!='00':
    en premier.



    Et pousser ausi la recherche d’optimisation en tenant compte de ce qui se passe avant et après les 6 mnn (maintenant 3mn30) de conversion.




    PS:

    Comme on fait ’$’.join(...) , je me dis que ces ’$’ sont sans doute en rapport avec l’écriture $var des variables en PHP.
    Je profite du changement de serveur pour basculer les traitements VB98 vers python et PHP.
    À quoi sert PHP dans l’histoire ? Pourquoi garder un tel canard boiteux ? Je suis sûr que Python arriverait à remplir sa tâche aussi bien.

  5. #25
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 34
    Points : 13
    Points
    13
    Par défaut
    Bonjour,
    Eyquem a posté beaucoup de choses, donc du bon et du moins bon.

    petits rappels:
    l'exemple qui est donné concerne un fichier (une table) sur 250.
    L'écriture d'une fonction peu utilisée dans l'exemple, l'est forcément plus dans l'ensemble du traitement.
    L'utilisation de fonctions est un compromis entre la lisibilité du programme et ses performances.
    La version du code utilisé le 7 août était celle du #19.

    Le bon : PGey1
    La concaténation par tuple out et outFile.write('$'.join(out)) est plus rapide de 16-18% par rapport aux autres méthodes.

    La reconnaissance du signe par indirection via le dictionnaire est 10% plus rapide que la version avec if-else, mais c'est négligeable.
    L'intérêt principal du dictionnaire est de pouvoir supprimer des appels de fonction et de remonter la détermination du signe dans le corps du programme sans altérer la lisibilité.

    En appliquant ces 2 méthodes, le temps d'exécution est passé de 6 à 4,1 secondes.

    Le moins bon :
    PGey2, on utilisait ce mode de lecture par blocs d'enregistrement il y a une trentaine d'années, mais c'était totalement transparent au niveau du code.
    La lecture enregistrement par enregistrement ou tout le fichier d'un coup me paraissent de meilleures solutions.

    >>"".ljust(10, ' ') dans la fonction trt_date(d) est assez cocasse.
    Si tu as mieux, je suis preneur.

    >>je me dis que ces ’$’ sont sans doute en rapport avec l’écriture $var des variables en PHP.
    pas du tout, j'utilise fréquemment le $ ou la £ comme délimiteurs de champs.

    >>À quoi sert PHP dans l’histoire ? Pourquoi garder un tel canard boiteux ? Je suis sûr que Python arriverait à remplir sa tâche aussi bien.
    C'est possible, mais on fait comme on peut et avec ce qu'on a.
    Si la documentation francophone de Python était à la hauteur de celle du PHP, je serais peut-être d'un autre avis.

    Pour l'heure j'utilise les deux en fonction de mes humeurs. En l'espèce les 250 programmes Python sont générés par du code PHP.

    J'allais oublier : merci pour le bon.

  6. #26
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    l'exemple qui est donné concerne un fichier (une table) sur 250.
    L'écriture d'une fonction peu utilisée dans l'exemple, l'est forcément plus dans l'ensemble du traitement.
    L'utilisation de fonctions est un compromis entre la lisibilité du programme et ses performances.
    Tu veux dire que parce qu’une fonction sera plus utilisée dans l’ensemble, ça vaut la peine de garder des actions sous forme de fonction pour raison de lisibilité ?

    Ce n’est pas mon avis.

    - Si un appel de fonction est mange-temps (je ne suis pas sûr que ce soit tout le temps le cas, je reste prudent), et que l’objectif est de réduire le temps d’exécution, alors a-t-on vraiment le choix ?

    - Pour moi, des petits bouts de fonction comme trt_packdec(s, d) et trt_date(d) entravent plus la perception globale d’un code qu’ils n'assurent sa lisibilité.

    - L’absence d’une fonction peut être compensée par des commentaires plus nombreux et fournis dans tout le code.

    - On ne regarde pas un code tout les jours. Rendre un programme plus lent au prétexte qu’on veut le comprendre plus rapidement quand on le regardera épisodiquement ne tient pas la route, de mon point de vue. Python a une syntaxe claire qui est propice à une meilleure maintenabilité que dans d’autres langages. il faut arriver à se défaire des mauvaises habitudes prises avec les autres langages.

    Mais ce n’est que mon avis personnel à moi.






    La version du code utilisé le 7 août était celle du #19.
    Je ne comprends pas. Le 7 août, il y a eu un post, de moi, et dans les codes présentés il n’y a pas de recours à memoryview qu'il y a dans #19






    La concaténation par tuple out et outFile.write('$'.join(out)) est plus rapide de 16-18% par rapport aux autres méthodes.
    La reconnaissance du signe par indirection via le dictionnaire est 10% plus rapide que la version avec if-else, mais c'est négligeable.
    Tu trouves que 10 % c’est négligeable mais pas 16-18 %

    L'intérêt principal du dictionnaire est de pouvoir supprimer des appels de fonction et de remonter la détermination du signe dans le corps du programme sans altérer la lisibilité.
    Ah, tu partages l'idée qu'éliminer des appels de fonction a de l'intérêt.

    Pourtant en appliquant ces 2 méthodes, le temps d'exécution est passé de 6 à 4,1 secondes.
    Cela fait -31 % , presque un tiers de temps en moins.
    Mais 16-18 % + 10 % = 26-28 % . Même si 10 % est peu d’après toi, l’apport du dictionnaire amplifie le bénéfice de l’autre modif.








    PGey2, on utilisait ce mode de lecture par blocs d'enregistrement il y a une trentaine d'années, mais c'était totalement transparent au niveau du code.
    Comprends pas.

    Tu veux dire que ce programme tournait déjà il y a 30 ans dans votre entreprise ? Ou que c’est une technique dépassée ? Pourquoi serait ce à bannir pour cause d’ancienneté, si ça accélère l’exécution ?

    « totalement transparent au niveau du code » , ça veut dire quoi ?






    La lecture enregistrement par enregistrement ou tout le fichier d'un coup me paraissent de meilleures solutions.
    Pourquoi ?






    >>"".ljust(10, ' ') dans la fonction trt_date(d) est assez cocasse.
    Si tu as mieux, je suis preneur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    print 'A' +  ''.ljust(10, ' ') + 'Z'
    print 'A' +   '%-10s' % ' '    + 'Z'
    print 'A' +      10*' '        + 'Z'
    print 'A' +    '          '    + 'Z'
    La dernière formule se trouve d’ailleurs dans mes codes, car c’est celle que je préfère.




    >>À quoi sert PHP dans l’histoire ? Pourquoi garder un tel canard boiteux ? Je suis sûr que Python arriverait à remplir sa tâche aussi bien.
    C'est possible, mais on fait comme on peut et avec ce qu'on a.
    Si la documentation francophone de Python était à la hauteur de celle du PHP, je serais peut-être d'un autre avis.
    Par hauteur, il faut entendre quantité je présume, car pour ce qui est de la qualité, celle de la doc de Python est à mon sens bien meilleure que celle de la filandreuse doc de PHP.

    Pour ce qui est de Python, tu as raison, il semble n’y avoir aucune doc exhaustive et à la page en français. C’est un mauvais point.






    En l'espèce les 250 programmes Python sont générés par du code PHP.
    Des programmes Python générés par du PHP ? Il doit y avoir quelque chose qui m’a échappé.






    --------------------------------------------------------------


    D’autre part, la réapparition de cette file me fait penser que j’ai oublié de poster un code qui améliore encore la vitesse d’exécution qui est passée en dessous de 50 % par rapport au premier code du message #24 qui est claqué sur un code de avi3000.

    Les changements:

    - pack = dict(zip('0123456789abcdef','%%%%%%%%%%%%%-%+'))
    comme argument par défaut : la création de l’objet dictionnaire pack n’est faite qu’une fois.
    À chacun des appels de trt_act() sur les 255 fichiers après le premier traité, pack existe déjà et n’est pas recréé.
    Ce n’est pas ça qui va influer sur la vitesse mais bon....


    Et ce qui est susceptible d’augmenter la vitesse d’exécution:


    - def trt_date(aaaa,mm,jj) au lieu de def trt_date(d)


    - dans PGey2,
    on fournit un morceau de fichier inChunk qui est passé comme argument à outing(inChunk) , fonction dans laquelle inChunk est transformé en hexadécimal par segments de 47 octets pour produire des objets inHex
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for k in xrange(0,len(inChunk), 47):
        inHex = hexlify(inChunk[k:k+48])
    Idée: faire la transformation de inChunk en hexadécimal une seule fois et itérer en obtenant les inHex par découpage du résultat de la transformation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    inHexTot = hexlify(inChunk)
    def outing(inChunk, inHexTot, datage = trt_date):
        for k in xrange(0,len(inChunk), 47):
            inHex = inHexTot[2*k:2*k+94]

    - j’ai choisi de calculer inHexTot dans le while , a l’extérieur de outing() , et de le passer en argument à outing()
    au lieu de passer inChunk à outing() et de calculer inHexTot dans outing() :
    il n’y a pas de raison déterminante pour l’une ou l’autre possibilité.
    Elles sont à mon avis équivalentes, il faut dans les deux cas passer un objet en arguments.

    Par contre, dans l’une ou l’autre possibilité, il est préférable de passer la donnée inChunk ou inHexTot en argument à outing() :
    cela évite à outing() de chercher cet objet à l’extérieur de son espace de nom
    The execution of a function introduces a new symbol table used for the local variables of the function. More precisely, all variable assignments in a function store the value in the local symbol table; whereas variable references first look in the local symbol table, then in the local symbol tables of enclosing functions, then in the global symbol table, and finally in the table of built-in names.
    http://docs.python.org/tutorial/cont...ning-functions
    Passé en argument, c’est en fait l’adresse qui est passée: outing() sait alors tout de suite où aller chercher la donnée en mémoire.


    - dans le même ordre d’idée, en passant la fonction trt_date() en argument à outing() , on lui évite de devoir à chaque fois aller la chercher à l’extérieur d’elle.


    Concernant ces deux derniers points, je crois que le fait que outing() est une fonction génératrice ne change rien au fait que si un objet situé à l’extérieur est utilisé dans la fonction, elle est obligée d’aller le chercher dans l'espace de noms extérieur: c’est un objet libre et qui reste libre, et non pas un objet défini dans la fonction et qui serait à ce titre enregistré dans l’espace de nom local.
    If a variable is used in a code block but not defined there, it is a free variable.
    http://docs.python.org/reference/exe...ng-and-binding


    - enfin le plus déterminant sur la vitesse est de remplacer
    outFile.write(''.join(line for line in outing(....)))
    par
    outFile.write(''.join(outing(....)))
    Étonnant.




    Résultats, pour nn = 200000

    PGey3 / PGavi = 47,5 % avec taille_chunk = 47000
    PGey3 / PGavi = 47,1 % avec taille_chunk = 94000

    Sur la base des temps minimaux, car ce sont ceux qui représentent le mieux la célérité intrinsèque d’un programme.






    J’ai aussi essayé deux idées supplémentaires:

    - fixer le buffering à 0:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    with open('packed_file'+str(taille_chunk), 'r', 0) as inFile, \
    open('mis_a_plat'+str(taille_chunk), 'w', 0) as outFile:
    - traiter des morceaux inChunk qui soient des multiples de 128,264,512,1024,2048,4096... etc
    en fixant taille_chunk par exemple à 47 x 1024


    Je n’ai constaté aucun accroissement de vitesse en les mettant en application.



    ------------------------------------------------

    Il y a d’autres pistes à explorer pour diminuer encore le temps d’exécution:



    http://psyco.sourceforge.net/



    http://cython.org/



    http://www.scipy.org/Weave



    http://python.net/crew/theller/ctypes/
    http://docs.python.org/library/ctypes.html
    en français:
    http://wikipython.flibuste.net/Ctypes



    mais je vais te laisser faire car je ne connais rien à ces modules.

  7. #27
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 34
    Points : 13
    Points
    13
    Par défaut
    Bonjour,
    J'ai une chaîne de 4 caractères contenant un entier que je dois convertir.
    Les containtes de performance sont à prendre en compte.

    J'ai codé comme ci-dessous, mais si vous avez mieux ou plus beau,
    je suis preneur.

    Merci

    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
    n = 20000
    nb = '\x00\x01\x01\x01'  
    t1 = time()
     
    i = 0
    for fois in xrange(n):
        i = 0
        for j in xrange(4) :
            i += ord(nb[j]) * (256**(3-j))
            z = str(i)
     
    print 'z='+  z
    65793     #ce qui est vrai et juste
    print 'trt 1: ' + str(time() - t1)
    trt : 16.78799

  8. #28
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Il serait sage de dire ce qu'on doit faire et mesurer car les 2 petites modifications ci dessous améliorent sensiblement les choses...
    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
    n = 20000
    nb = '\x00\x01\x01\x01'  
    t1 = time()
     
    #i = 0
    for fois in xrange(n):
        i = 0
        for j in xrange(4) :
            i += ord(nb[j]) * (256**(3-j))
            #z = str(i)
        z = str(i)
     
    print 'z='+  z
    65793     #ce qui est vrai et juste
    print 'trt 1: ' + str(time() - t1)
    trt : 16.78799
    Mais çà dépend de ce qu'on veut mesurer.
    Pourquoi ne pas reformuler cela sous la forme d'une fonction avec les paramètres d'entrées et de sortie sont une bonne "bordure" pour çà.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #29
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 34
    Points : 13
    Points
    13
    Par défaut
    La demande ne portait que sur la partie de code ci-dessous.

    Le reste ne sert que pour les tests et ne présente aucun intérêt.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    nb = '\x00\x01\x01\x01'  
    i = 0
    for j in xrange(4) :
            i += ord(nb[j]) * (256**(3-j))
    z = str(i)
    la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def trt_bin(b):
        """  traitement des binaires"""
        i = 0
        for j in xrange(4) :
            i += ord(b[j]) * (256**(3-j))
     
        return str(i)

  10. #30
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 046
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 046
    Points : 1 376
    Points
    1 376
    Par défaut
    pas beaucoup plus performant(1,4 fois plus rapide quand même) mais moins tordu
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    nb = 'abcd'
    i=0
    for j in nb: i=(i<<8)+ord(j)
    z = str(i)

  11. #31
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    time.clock()

    On Unix, return the current processor time as a floating point number expressed in seconds. The precision, and in fact the very definition of the meaning of “processor time”, depends on that of the C function of the same name, but in any case, this is the function to use for benchmarking Python or timing algorithms.

    On Windows, this function returns wall-clock seconds elapsed since the first call to this function, as a floating point number, based on the Win32 function QueryPerformanceCounter(). The resolution is typically better than one microsecond.


    S’il n’y a toujours que 4 chiffres dans le nombre nb .... :

    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
    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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    from time import clock
    from binascii import hexlify
    n = 2000
    nb = '\x05\x3A\x01\xDE'
    print "ord('\\xff') = ",ord('\xff')
    print 'nb =',''.join(map(lambda u: '\\'+'x'+hexlify(u), nb))
    print
     
    avi,A,B,C,D,E = [],[],[],[],[],[]
    rep = 50
     
    #----------------------------------------------
    for repet in xrange(rep):    
        t0 = clock()
        for fois in xrange(n):
            i = 0
            for j in xrange(4) :
                i += ord(nb[j]) * (256**(3-j))
        avi.append(clock()-t0)
    print 'i =',i,'  avi'
     
    #----------------------------------------------
    deek = {3:1,2:256,1:65536,0:16777216}
    for repet in xrange(rep):
        t0 = clock()
        for fois in xrange(n):
            i = sum( ord(nb[j]) * deek[j] for j in xrange(4) )
        A.append(clock()-t0)
    print 'i =',i,'  A'
     
    #----------------------------------------------
    deek = {3:1,2:256,1:65536,0:16777216}
    for repet in xrange(rep):
        t0 = clock()
        for fois in xrange(n):
            i = 0
            for j in xrange(4) :
                i += ord(nb[j]) * deek[j]
        B.append(clock()-t0)
    print 'i =',i,'  B'
     
    #----------------------------------------------
    for repet in xrange(rep):
        t0 = clock()
        for fois in xrange(n):
            i = 0
            for (m,u) in ((16777216,nb[0]),(65536,nb[1]),(256,nb[2]),(1,nb[3])):
                i += ord(u) * m
        C.append(clock()-t0)
    print 'i =',i,'  C'
     
    #----------------------------------------------
    for repet in xrange(rep):
        t0 = clock()
        for fois in xrange(n):
            i = 16777216*ord(nb[0]) + 65536*ord(nb[1]) + 256*ord(nb[2]) + ord(nb[3])
        D.append(clock()-t0)
    print 'i =',i,'  D'
     
    #----------------------------------------------
    def treat_bin(nb):
        return 16777216*ord(nb[0]) + 65536*ord(nb[1]) + 256*ord(nb[2]) + ord(nb[3])
     
    for repet in xrange(rep):
        t0 = clock()
        for fois in xrange(n):
            i = treat_bin(nb)
        E.append(clock()-t0)
    print 'i =',i,'  E'
     
    #===============================================
    print '\n   secondes'
    print '  ',str(min(avi))[0:8],'  code de reference avi '
    print '   --------   ----------------------------------------------'
    print 'A ',str(min(A))[0:8],'  sum( ord(nb[j]) * deek[j] for j in xrange(4) )'
    print 'B ',str(min(B))[0:8],'  i += ord(nb[j]) * deek[j]'
    print 'C ',str(min(C))[0:8],'  for (m,u) in ((16777216,nb[0]),......)'
    print 'D ',str(min(D))[0:8],'  i = 16777216*ord(nb[0]) + 65536*ord(nb[1])....'
    print 'E ',str(min(E))[0:8],'  i = treat_bin(nb)'
    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
    ord('\xff') =  255
    nb = \x05\x3a\x01\xde
     
    i = 87687646   avi
    i = 87687646   A
    i = 87687646   B
    i = 87687646   C
    i = 87687646   D
    i = 87687646   E
     
       secondes
       0.039467   code de reference avi 
       --------   ----------------------------------------------
    A  0.038304   sum( ord(nb[j]) * deek[j] for j in xrange(4) )
    B  0.037361   i += ord(nb[j]) * deek[j]
    C  0.032957   for (m,u) in ((16777216,nb[0]),......)
    D  0.014271   i = 16777216*ord(nb[0]) + 65536*ord(nb[1])....
    E  0.013791   i = treat_bin(nb)

    J'ai fixé n à 2000 parce que mon ordinateur est lent.




    Par ailleurs, est-ce que tu as vu mon message #26 posté depuis ton dernier passage ?
    Quelques petites améliorations dans mon code ont fait descendre le temps d’exécution à 47 % du temps de ton code initial.

  12. #32
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    mon dernier mot:
    on déplie et on accélère via locals
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    M = [ 24, 16, 8, 1]
    def trt_bin(b):
        """  traitement des binaires"""
        lord = ord
        m = M
        r = (lord(b[0]) << M[0]) + (lord(b[1]) << M[1]) + (lord(b[2]) << M[2]) + (lord(b[3]) << M[3])
        return str(r)
    comparé à l'orginal qui chez moi donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    z=  65793
    trt_bin_1: 0.091716 s.
    il sort:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    z=  65793
    trt_bin_x: 0.053163 s.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  13. #33
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 046
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 046
    Points : 1 376
    Points
    1 376
    Par défaut
    je suppose que c'est:
    et non:

  14. #34
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 046
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 046
    Points : 1 376
    Points
    1 376
    Par défaut
    effectivement, si la longueur de la chaine est constante ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def trt_bin(b):
    	a,b,c,d=bytearray(b)
    	return str((a<<24)+(b<<16)+(c<<8)+d)
    mais le code de wiztricks est plus rapide.
    ord() est plus rapide que bytearray
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    def trt_bin(b):
    	return str((ord(b[0])<<24)+(ord(b[1])<<16)+(ord(b[2])<<8)+ord(b[3]))

  15. #35
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,
    A la réflexion, c'est quand même un peu dommage de faire tout çà alors que
    int('0x00010101', 16) ferait faire ces mêmes opérations plus près du processeur.
    A défaut de pouvoir remplacer les arguments reçus, comment faire proche de... avec struct unpack çà donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def trt_bin_6(b, l=unpack, s=str):
        return s(l('>L',nb)[0])
    def trt_bin_61(b):
        return str(unpack('>L',nb)[0])
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    z=  65793
    trt_bin_6: 0.029141 s.
    z=  65793
    trt_bin_61: 0.029359 s.
    c'est "mieux" comparé à trt_bin_x: 0.053163 s.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  16. #36
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 34
    Points : 13
    Points
    13
    Par défaut
    Bonjour et merci pour les réponses.

    Résultat des tests:

    • 1er: trt_bin_61 de wiztricks 0.0939
      return str(unpack('>L',nb)[0])

    • 2ème: treat_bin d'eyquem 0.1719
      return 16777216*ord(nb[0]) + 65536*ord(nb[1]) + 256*ord(nb[2]) + ord(nb[3])

    • 3ème: trt_bin n°2 de josmiley 0.2650
      return str((ord(b[0])<<24)+(ord(b[1])<<16)+(ord(b[2])<<8)+ord(b[3]))

    • bon dernier, mon trt_bin 0.3120
      c'est normal, j'avais un for


    Le n°2 et le n°3 sont facilement compréhensibles.
    Le n°1 est plus concis, mais on est obligé de faire confiance au unpack.
    si wiztricks peut nous en dire un peu plus, ça aidera notre réflexion.

    @eyquem
    j'ai lu et testé des parties du #26.
    j'en ai repris certaines.

    @wiztricks
    int('0x00010101', 16), mais ça ne correspond pas à mes données.

  17. #37
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Salut wiztricks,

    Encore un truc intéressant que tu mets sur le tapis.

    Je ne connais pas le module struct. J’ai jeté un coup d’œil mais je ne comprends pas le signe ’>’:
    The ‘Standard size’ column refers to the size of the packed value in bytes when using standard size; that is, when the format string starts with one of '<', '>', '!' or '='.

    http://docs.python.org/library/struc...mat-characters
    Une petite explication ?











    J’ai aussi fait des tas de tests avec diverses possibilités. Ce que j’ai de plus rapide est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    def treat_binF(nb,lord = ord):
        return lord(nb[0])*16777216 + lord(nb[1])*65536 + lord(nb[2])*256 + lord(nb[3])
    Passer un objet (en fait l'adresse d'un objet), nécessaire au calcul dans une fonction, en tant qu’argument par défaut donne une vitesse plus élevée dans une exécution répétée.



    J’essaye de comprendre l’utilisation des fonctions du module struct pour inclure ce calcul dans ma série de tests. Mais il semble bien que ça va être le plus rapide de tout.

  18. #38
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    Citation Envoyé par eyquem Voir le message
    Je ne connais pas le module struct. J’ai jeté un coup d’œil mais je ne comprends pas le signe ’>’:
    Salut eyquem,

    il s'agit des conventions little et big endian. Un petit lien vaut mieux qu'un long discours sur l'endianness.

  19. #39
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 34
    Points : 13
    Points
    13
    Par défaut
    Endianness

    merci kango

  20. #40
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par avi3000 Voir le message
    Endianness

    merci kango
    Yes.

    Vérifiez quand même pourquoi l'endianess du contenu de vos fichiers est 'big'.
    C'est lié à comment ils sont construits, mais quelque soit l'algorithme utilisé pour reconstruire les "long", si on se plante sur le MSB ou la taille çà ne fera pas des trucs "drôles".

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

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 3 PremièrePremière 123 DernièreDernière

Discussions similaires

  1. Comment obtenir offset de String dans une chaine
    Par L4BiN dans le forum API standards et tierces
    Réponses: 1
    Dernier message: 09/07/2009, 13h42
  2. Réponses: 2
    Dernier message: 03/10/2005, 16h23
  3. Réponses: 2
    Dernier message: 14/01/2005, 15h40
  4. comment vider une chaine de caractère
    Par gaut dans le forum C
    Réponses: 13
    Dernier message: 12/09/2003, 11h30
  5. Réponses: 2
    Dernier message: 06/12/2002, 07h50

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