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 :

Quoi de plus rapide qu'un dictionnaire ?


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Par défaut Quoi de plus rapide qu'un dictionnaire ?
    Salut,

    Voilà, par simple curiosité, j'ai comparé 3 classes équivalentes (une dérivée de ctypes.Structure avec bit_field, une autre classique dérivée de object et possedant un __slots__ et enfin une faite en pyrex compilé), une liste et un dico.

    Code de la classe en pyrex :
    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
    cdef class Case:
    	cdef int _walkable,_explodable,_stuntable
    	cdef object parent
    	def __cinit__(self,int w, int e, int s, parent=None):
    		self._walkable=w
    		self._stuntable=s
    		self._explodable=e
    		self.parent=parent
    	property walkable:
    		def __get__(self):
    			if self._walkable:
    				return True
    			else:
    				return False
    		def __set__(self,value):
    			if value:
    				self._walkable=1
    			else:
    				self._walkable=0
    		def __del__(self):
    			pass
    	property explodable:
    		def __get__(self):
    			if self._explodable:
    				return True
    			else:
    				return False
    		def __set__(self,value):
    			if value:
    				self._explodable=1
    			else:
    				self._explodable=0
    		def __del__(self):
    			pass
    	property stuntable:
    		def __get__(self):
    			if self._stuntable:
    				return True
    			else:
    				return False
    		def __set__(self,value):
    			if value:
    				self._stuntable=1
    			else:
    				self._stuntable=0
    		def __del__(self):
    			pass
    le code des deux autres classes (ct=ctypes):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Case(ct.Structure):
        _fields_=[("walkable",ct.c_ushort,1),
              ("explodable",ct.c_ushort,1),
              ("stuntable",ct.c_ushort,1),
              ("parent",ct.py_object)]
     
    class Case2(object):
        __slots__=tuple('walkable stuntable explodable parent'.split())
        def __init__(self,w=0,e=0,s=0,p=None):
            self.walkable=w
            self.explodable=e
            self.stuntable=s
            self.parent=p
    La fonction time utilisée dans le code ci-après est une fonction qui execute la liste de blocs textes passée en paramètre et retourne un tuple des temps d'execution de chaque bloc, et pp=pprint.pprint
    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
    a=Case(0,0,0)
    b=Case2(0,0,0)
    c=C_case.Case(0,0,0)
    d=[0,0,0,0]
    e={'walkable':0,'explodable':0,'stuntable':0,'parent':None}
     
    codes=[
    '''for x in range(1000):
        if a.walkable: a.walkable=0
        else: a.walkable=1''',
    '''for x in range(1000):
        if b.walkable: b.walkable=0
        else: b.walkable=1''',
    '''for x in range(1000):
        if c.walkable: c.walkable=0
        else: c.walkable=1''',
    '''for x in range(1000):
        if d[0]: d[0]=0
        else: d[0]=1''',
    '''for x in range(1000):
        if e['walkable']: e['walkable']=0
        else: e['walkable']=1''']
    tab=[time(codes) for x in range(500)]
    res=[]
    for x in range(len(tab[0])):
        res+=[sum(y[x] for y in tab)/len(tab)]
    pp(res)
    et voici les résultats :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    >>> 
    [0.00037558209962526237, # module ctypes
     0.00032265495207911955, # classique
     0.00028882434114848367, # pyrex
     0.00024732920097676471, # liste
     0.00024037783677704282] # dico
    >>>
    Et ma question est la suivante : connaissez-vous un moyen d'obtenir une classe (ou autre objet, même si j'ai une préférence pour les classes...) plus rapide qu'un dico ou une liste (je deteste ecrire les "[]" et encore plus les "['']" ) ?

  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
    J'ai fait un petit test:
    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
    from timeit import Timer
     
    class A(object):
        def __init__(self):
            self.x = 0
     
    class B(object):
        __slots__= ('x',)
        def __init__(self):
            self.x = 0
     
    class C:
        def __init__(self):
            self.x = 0
     
    a = A()
    b = B()
    c = C()
    s1 = "a.x = 1 - a.x"
    s2 = "b.x = 1 - b.x"
    s3 = "c.x = 1 - c.x"
    s4 = "x = 1-x"
    print s1, '-->', Timer(s1, "from __main__ import a").timeit()
    print s2, '-->', Timer(s2, "from __main__ import b").timeit()
    print s3, '-->', Timer(s3, "from __main__ import c").timeit()
    print s4, '-->', Timer(s4, "x = 0").timeit()
    Résultats:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    a.x = 1 - a.x --> 0.210127823508
    b.x = 1 - b.x --> 0.175828492169
    c.x = 1 - c.x --> 0.14965756821
    x = 1-x --> 0.0505745841999
    Donc:
    • les "old-style classes" sont plus rapides que les "new-style classes", même avec __slots___. Mais bon, comme les "old-styles classes" n'existent plus dans Python 3.0, ce n'est peut-être pas une bonne idée d'en dépendre.
    • Ce qui est lent c'est le lookup de l'attribut, comme le montre le dernier test. Cela ne répond pas à ta question mais si tu accèdes plusieurs fois à un attribut dans une fonction, tu as tout intérêt à créer un alias local (ou travailler sur une variable locale avec une assignation à l'attribut à la fin) pour éviter de payer le prix du lookup plusieurs fois.

    [EDIT: corrections]

  3. #3
    Membre émérite
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Par défaut
    Oui, faudra que je garde ça en memoire, comme je développe un jeux avec panda, le moindre gain de temps est le bienvenu...

    Mais, pour faire plus rapide, j'me dis que je devrais peut-être commencer à apprendre le C et le C++ pour faire certain des modules... mais quand je vois déjà le language, et en plus l'API Python... pffiuo, ch'uis épuisé , enfin, autant faire d'abord en python, puis si nécéssaire, j'y viendrai au C...

    Donc ma question reste toujours d'actualité, même si j'ai franchement peu d'espoir... peu-être un array dynamique en C, mais quel bordel...

Discussions similaires

  1. Réponses: 5
    Dernier message: 24/11/2011, 09h44
  2. Réponses: 0
    Dernier message: 03/08/2011, 23h53
  3. [FB1.5]Quelle est la requete la plus rapide ?
    Par Sitting Bull dans le forum SQL
    Réponses: 4
    Dernier message: 10/12/2004, 13h46
  4. [VB6] timer plus rapide que 1 d'interval
    Par windob dans le forum VB 6 et antérieur
    Réponses: 12
    Dernier message: 24/02/2004, 00h16
  5. Réponses: 8
    Dernier message: 31/10/2003, 16h21

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