Partage
  • Partager sur Facebook
  • Partager sur Twitter

compresser allocation memoire objet

Sujet résolu
    18 mai 2015 à 10:16:51

    Bonjour, comment compresser un objet en python ?, en regardant sur la doc, j'ai ceci:

    import cPickle
    import zlib
    
    obj=monobjet
    compressed = zlib.compress(pickle.dumps(obj))
    
    

    Se serait pour réduire l'impacte mémoire pour que cpikle puisse pikler un gros objet (sans avoir de memory error)

    • Partager sur Facebook
    • Partager sur Twitter
      18 mai 2015 à 11:38:01

      Ca ne marchera pas étant donné qu'avant d'appeler zlib.compress, il va devoir appeler pickle.dumps(objet) qui lui apparemment te cause un problème mémoire.

      L'idée serait plutôt de morceler ton objet.

      -
      Edité par Dan737 18 mai 2015 à 12:33:06

      • Partager sur Facebook
      • Partager sur Twitter
      Anonyme
        18 mai 2015 à 12:08:17

        Comme le dit Dan737, pickle.dump créer une chaîne de bytes contenant l'objet sérialisé et la MemoryError arrive quand cette chaîne est trop longue. Donc l'erreur se déclenchera avant que zlib.compress ne la reçoive.

        Quel est cet objet si imposant en taille ? Une liste ? Si c'est ça, le plus simple est de pickler les éléments de la liste un à un dans ton fichier :

        # pickling...
        with open(FILENAME, "wb") as file:
            for element in LIST:
                pickle.dump(element, file)
        
        # unpickling...
        with open(FILENAME, "rb") as file:
            ls = []
            try:
                while True:
                    ls.append(pickle.load(file))
            except EOFError:
                pass
        

        J'ai pas testé, mais l'idée est là.

        • Partager sur Facebook
        • Partager sur Twitter
          18 mai 2015 à 12:18:20

          Oui c'est effectivement une liste de liste,

          Je n'y ai pas penser car je croyait que pickle ne pouvais crée qu'un fichier/donnée, d’après le code de celton (pas encore testé, je tente cette après midi), on peut décomposer le dump, se qui pourrais donc régler mon problème, assez simplement.

          • Partager sur Facebook
          • Partager sur Twitter
            18 mai 2015 à 12:37:11

            Et sur Stackoverflow t'as même un exemple qui charge tes objets un à un, vu que c'est un générateur. Enfin à toi de voir ce qui est nécessaire.

            • Partager sur Facebook
            • Partager sur Twitter
              19 mai 2015 à 10:50:19

              Il y'a un léger mieux, mais parfois c'est pas encore suffisant.

              Je pense donc que la solution serait de faire passer un élément de la liste de la liste a la fois.

              import _pickle as pickle
              import os 
              
              FILENAME="test.tmp"
              LIST=[1,2,3,4,5,6,7,8,9]
              list2=[LIST,LIST,LIST,LIST]
              
              # pickling...
              with open(FILENAME, "wb") as file:
              	for i in range(0,len(list2)):
              		for element in list2[i]:
              			pickle.dump(element, file)
              
              		
              os.system("pause")
              	
              	
              
              # unpickling...
              with open(FILENAME, "rb") as file:
                  ls = []
                  try:
                      while True:
                          ls.append(pickle.load(file))
                  except EOFError:
                      pass
              		
              print(ls[0])

              Pour le pikler sa marche très bien, mais c'est pour recomposer la liste que sa plante, comment lui dire que les 9 premier éléments sont a la liste1 ?
              J'ai penser a stocker la tailles de chaque liste dans une liste.... mais sa vas encore consommer de la ram.

              -
              Edité par zearte 19 mai 2015 à 10:51:07

              • Partager sur Facebook
              • Partager sur Twitter
              Anonyme
                19 mai 2015 à 12:01:41

                Avant de continuer à parler de Pickle, dis-nous que fait ton programme exactement, à quoi il sert ? Et surtout, que contiennent ces listes et à quoi elles servent ?

                Soit ton programme est mal conçu, sauf cas précis, il n'est pas normal d'avoir des listes qui consomment autant de mémoire. Soit Pickle n'est pas la solution pour sauvegarder leurs contenus, et il faudra voir du côté de SQLite, par exemple.

                Ceci dit, si tu tiens obstinément à rester sur du pickling, c'est à toi de déterminer comment structurer ton fichier pour pouvoir lire et écrire dedans à ta guise.

                • Partager sur Facebook
                • Partager sur Twitter
                  19 mai 2015 à 12:02:05

                  Il ne faut pas stocker mais écrire dans le fichier la taille de tes sous-listes.

                  !/usr/bin/env python3

                  -- encoding: utf-8 --

                  import pickle

                  FILENAME = "test.tmp" LIST = list(range(1, 10)) list2 = [LIST, LIST, LIST, LIST]

                  pickling...

                  with open(FILENAME, "wb") as file:

                  for sub_list in list2:
                      pickle.dump(len(sub_list), file)
                      for element in sub_list:
                          pickle.dump(element, file)
                  
                       
                  

                  input('Les données sont sauvegardées. Pressey ENTER pour les charger')

                  unpickling...

                  with open(FILENAME, "rb") as file:

                  loaded_list = []
                  try:
                      while True:
                          sub_list = []
                          sub_list_size = pickle.load(file)
                          for _ in range(sub_list_size):
                              sub_list.append(pickle.load(file))
                          loaded_list.append(sub_list)
                  except EOFError:
                      pass
                       
                  

                  print(loaded_list)

                  </pre> Attention à ton utilisation des boucles for. On ne devrait jamais écrire
                  li = list(range(10))
                  for i in range(len(li)):
                  
                  print(li[i]) # Beurk
                  

                  for element in li:

                  print(element) # Ah, là c'est mieux!
                  
                  </pre>

                  -
                  Edité par Dan737 19 mai 2015 à 12:02:18

                  • Partager sur Facebook
                  • Partager sur Twitter
                    19 mai 2015 à 15:46:15

                    Ok, j'avais pas compris.
                    • Partager sur Facebook
                    • Partager sur Twitter

                    compresser allocation memoire objet

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown