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 :

List append performance


Sujet :

Python

  1. #1
    Membre confirmé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 106
    Par défaut List append performance
    Bonjour

    N'étant pas un pro python, je cherche à comprendre une bizarrerie que je rencontre en Python v2.5.4.

    J'ai une liste (10000 éléments) de chaine de caractères que je parcours dans un for.
    Pour chaque chaine, je construis un objet qui est rajouté dans une autre liste.
    Voici mon code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    results = []
    #
    for xml : xml_list:
         # create object from xml
         obj = createObject(xml)
         # append obj in result
         results.append(obj)                   <---- pb de perfo
    Mon pb vient du results.append qui prends 5s sur un total de 15s.
    Si je commente la ligne qui fait le append, mon traitement prends 10s.
    Je pensais que c'était le append qui prenait du temps mais si au lieu de faire un results.append(obj), je fais un results.append(xml), mon traitement continue de prendre 10s.
    Donc c'est bien le fait de rajouter "un objet complexe" dans ma liste qui prends du temps mais je ne sais pas pourquoi.

    Qu'un aurait une explication?

    Merci

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

    voir la discussion
    votre code devrait marcher mieux avec les gc.disable/gc.enable ci dessous.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import gc
    results = []
    #
    gc.disable()
    for xml : xml_list:
         # create object from xml
         obj = createObject(xml)
         # append obj in result
         results.append(obj)  
    gc.enable()
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre confirmé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 106
    Par défaut
    Bonjour wiztricks

    Et merci pour ta réponse.
    J'ai essayé, je gagne une seconde de temps.

    Il me reste donc ces 4 secondes dans les bras

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

    Si ce n'est plus un problème connu Python 2.5, il faut peut être regarder l'utilisation de ressources comme RAM, IO disques, fichiers de pagination,...
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 049
    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 049
    Par défaut
    Vous avez essayé avec deque?

    Un exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> from collections import deque
    >>> liste = deque()
    >>> liste.append(5)
    >>> liste.append(12)
    >>> print liste
    deque([5, 12])

  6. #6
    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
    ... ou une list comprehension:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    results = [createObject(xml) for xml in xmlList]
    Si la liste de résultats n'est utilisée que de façon séquentielle, on peut même éviter de créer la liste et utiliser une generator expression:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    results = (createObject(xml) for xml in xmlList)

  7. #7
    Membre confirmé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 106
    Par défaut
    Bonjour à tous

    J'ai essayé de faire le deque et results = [createObject(xml) for xml in xmlList] mais j'obtiens les mêmes résultats

    Par contre, le parcours des objets de results = (createObject(xml) for xml in xmlList) est plus rapide car je retrouve mes 10s.

    mais je ne peux utiliser ca car mon API est utilisée par d'autres et je ne peux changer la liste de retour par un generator expression

    Je tiens à préciser que j'ai un pc assez rapide et que je ne perds que 5s tandis mon collègue ayant un pc moins rapide perds bcp plus dans ces appends.

    D'ou ma recherche d'une solution si elle existe.

  8. #8
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Normal que le générateur aille vite, puisqu’il ne crée rien d’autre qu’un itérateur, pas la liste elle-même…

    Peut-être ça?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    results = list((createObject(xml) for xml in xmlList))
    Mais de toute façon, je trouve étrange un tel effondrement des perfs pour un simple append (en python3, c’est quasi instantané, même avec la création de 100000 object()…).

  9. #9
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 695
    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 695
    Par défaut
    Citation Envoyé par mont29 Voir le message
    Mais de toute façon, je trouve étrange un tel effondrement des perfs pour un simple append (en python3, c’est quasi instantané, même avec la création de 100000 object()…).
    Me too.

    En fait, on ne crée pas d'objets mais des références à des objets.
    Les appends devraient être O(1) excepté lorsque la "capacité" de la liste doit être "augmentée".

    L'auteur dit: "Si je commente la ligne qui fait le append, mon traitement prends 10s."
    Si on traduit cela dans le code "montré", ces 10s. correspondent à la création des des objets mais leur place mémoire est libérée assez vite
    puisque l'assignation à obj libère la référence précédente.
    Lorsq
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  10. #10
    Membre confirmé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 106
    Par défaut
    Bonjour à tous

    En lisant vos remarques, j'ai voulu tester si c'était vraiment le append qui prenait du temps, j'ai donc rajouté après le append, un remove de l'objet.
    Et la, le temps mis est bcp moins long, je suis à un peu plus de 10s, mais cela ne sert à rien de retourner une liste vide .
    C'est donc le fait de stocker ces objets en mémoire qui prends du temps et non le append.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    results = []
    #
    for xml : xml_list:
         # create object from xml
         obj = createObject(xml)
         # append obj in result
         results.append(obj)
         #
         results.remove(obj)           <----- rajout
    Comme je pense qu'il n'y a pas de contournement (à part de generator expression), je vais mettre sur résolu.

    Merci à tous

  11. #11
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 103
    Par défaut
    Citation Envoyé par st20085 Voir le message
    Bonjour à tous

    En lisant vos remarques, j'ai voulu tester si c'était vraiment le append qui prenait du temps, j'ai donc rajouté après le append, un remove de l'objet.
    Et la, le temps mis est bcp moins long, je suis à un peu plus de 10s, mais cela ne sert à rien de retourner une liste vide .
    C'est donc le fait de stocker ces objets en mémoire qui prends du temps et non le append.
    Sauf que du coup la taille de ta liste n'augmente pas ... hors d'après le lien plus haut c'est ce point + le gc qui ralentit l'ajout.

  12. #12
    Membre confirmé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 106
    Par défaut
    Citation Envoyé par ZZelle Voir le message
    Sauf que du coup la taille de ta liste n'augmente pas ... hors d'après le lien plus haut c'est ce point + le gc qui ralentit l'ajout.
    Bonjour
    Effectivement la taille de ma liste n'augmente pas, cependant je ne pense pas que cela vienne du append, car si je fais le append sur mon xml au lieu de mon objet, la taille de la liste augmente bien mais le temps d'exécution reste à 10s au lieu de 15s

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

Discussions similaires

  1. Maps, Lists et performances
    Par atmakefka dans le forum Collection et Stream
    Réponses: 3
    Dernier message: 23/07/2010, 10h59
  2. Réponses: 4
    Dernier message: 30/01/2009, 15h20
  3. Performances avec des listes d'objets
    Par metalcoyote dans le forum Langage
    Réponses: 9
    Dernier message: 20/05/2008, 11h11
  4. [Performance] Différence entre List<T> et Collection<T>
    Par simone.51 dans le forum Framework .NET
    Réponses: 3
    Dernier message: 14/04/2008, 12h19
  5. Réponses: 3
    Dernier message: 25/04/2007, 09h45

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