Stockage de gros contenus dans des fichiers

Fermé
reboulip - 30 oct. 2012 à 14:39
 A.Nonymous - 31 oct. 2012 à 08:40
Bonjour,

Je souhaite stocker de gros objets de manière persistante, de manière à pouvoir y accéder sans avoir à les générer à chaque fois que j'en ai besoin. Pour cela, j'ai testé plusieurs solutions (cPickle, shelve...) et lu beaucoup de sujets sur le net, mais je ne trouve pas mon bonheur (malgré ma question sur l'écriture de fichiers binaires dans un autre sujet).

Pour situer les choses : je créé un gros objet (appelons-le "data"), dans lequel j'ai des objets "tuyaux" eux-mêmes composés d'objets "mailles". Je construis mon "data" une bonne fois pour toutes, mais je veux pouvoir accéder rapidement au contenu d'une maille.

Pour l'instant, je stocke l'objet "data" avec shelve, dans un fichier. Mais le problème, c'est que quand je cherche à ressortir le contenu d'une maille donnée (et seulement cette maille), dès la commande :


data = shelve.open("fichier")
mon programme charge l'intégralité du fichier en mémoire (donc y compris les autres objets que j'aurais stockés !).

Donc déjà ça prend pas mal de temps. Mais pire : ensuite, le temps d'accès à n'importe quel élément de l'objet met un temps fou à se charger.

Existe-t-il une solution permettant d'accéder au contenu du fichier sans que ça prenne des heures ?

Merci
A voir également:

3 réponses

Pourquoi ne pas utiliser un serveur de cache tel que Memcache(d), mongoDB, ou autre, ou même une mini-DB sqlite ?
1
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
30 oct. 2012 à 15:17
Salut.
je ne connais pas tes outils, je te fait une réponse plus générale.
J'ai aussi eu un problème dans ton genre, un gros fichier de données, contenant des sauvegardes à différents instants. Au lieu de tout charger à chaque fois et de re parcourir mon fichier en lisant chaque donnée, je me suis fait un index (ou sommaire), ce qui fait que j'ouvre le fichier en lecture, puis me déplace avec fseek à l'endroit voulu avant de lire mes données.
Tu peux regarder dans la documentation de shelve s'il est possible d'ouvrir le fichier sans tout charger et de faire des expèces d'index. Ou alors il faut que tu fasses toi même.
0
Salut, et merci pour ta réponse

Effectivement mon problème est assez proche de ce que tu décris : gros fichier de données (listing) à lire, et une quantité limitée d'infos à extraire. Le fichier en question est écrit par un autre logiciel, malheureusement je n'ai pas la main sur ce qu'il fait, ce qui rend la navigation assez peu robuste dans ce fichier.

J'ai parcouru la doc de shelve, mais je n'y ai rien trouvé de probant.

Tu proposes la solution du sommaire : si j'ai bien compris, c'est l'utilisation de mots-clefs pour naviguer plus rapidement dans le fichier. Ça peut être une bonne solution. Mais ça me fait penser qu'un autre logiciel que je connais (je ne peux pas accéder à ses sources...) écrit un fichier qu'il appelle "sommaire", et je sais qu'on peut accéder facilement et rapidement à son contenu quel que soit sa taille, avec un autre (oui encore un autre) logiciel (dont je ne peux pas lire les sources non plus !). Ce fichier "sommaire" est un binaire, n'est-il pas possible de faire la même chose avec python ? Je pensais à tort qu'avec un simple objet, ça fonctionnerait.

Finalement, peut-être que le traitement "instantané" (je vais chercher l'info quand j'en ai besoin) est plus efficace pour les gros fichiers de données.
0
Char Snipeur, merci pour cette réponse.

Imaginons que je charge l'objet en mémoire (un peu long mais supportable). Actuellement, j'accès aux données voulues en faisant :
toto = data.tuyaux[i].maille[j].pression[k]
Se pourrait-il que, par une astuce de programmation (ajout d'une méthode) je puisse accéder plus rapidement au contenu que je cherche (pression dans la maille j du tuyau i à l'instant k) ?

reboulip
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
31 oct. 2012 à 08:14
Salut.
Es tu sur que data.tuyaux[i].maille[j].pression[k] prenne beaucoup de temps ? il s'agit juste d'acces à un espace mémoire donné, ça devrait être rapide. Je connais pas les mécanismes python d'accès aux données. En C++, les opérateurs '.' et '[]' peuvent cacher des fonctions assez compliquées et donc gourmande. En C++, on pourrait s'en tirer en connaissant la structuration de la mémoire. Dans ton cas, il faut voir. Par exemple, si tu recherche plusieurs pressions dans la maille j, tu peux normalement gagner du temps en utilisant un objet intermédiaire :
maillej=data.tuyaux[i].maille[j]
(ça serait sur en C++ avec un pointeur, encore une fois en python, je ne sais pas).
0