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

Java Discussion :

Performance en lecture/ecriture d'une collection d'objet serializable ?


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5
    Par défaut Performance en lecture/ecriture d'une collection d'objet serializable ?
    Bonjour tout le monde,

    Voilà je m’initie à la programmation (Java) depuis peu et je suis confronté à un problème que je ne parviens pas à résoudre et je ne trouve pas d’infos sur le net.
    Mon cahier des charges est le suivant :
    J’ai un objetB qui est une liste d’ objetA serializable.
    Je dois pouvoir ajouter de nouveau objetA à mon objetB sur demande et ce dernier doit conserver toutes les entrées précédentes.
    Je dois aussi pouvoir récupérer tous les objetA ou un en particulier
    Voici, en gros, comment se construit mon objetB :
    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
    //Code simplifié à l'extreme
    public class ObjetB {
     
    	ArrayList<ObjetA> listObjetA = new ArrayList<ObjetA>() ;
     
    	public ObjetB(){
     
            File fichier = new File(path);
    		if(fichier.length() > 0) {
    			ObjectInputStream in = new ObjectInputStream(
    					New BufferedInputStream(
    						new FileInputStream(fichier)));
     
    			listObjetA = (ArrayList<listObjetA>)in.readObject();
    			in.close();
    		}
    	}
     }
    Pour ajouter un objetA pas de soucis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public void addObjetA(ObjetA objetA){
     
          listObjetA.add(objetA) ;
          serialize() ;  //Ici je serialize mon ArrayList
    }
    Et par exemple pour obtenir la desciption de mes ObjetA:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public String toString(){
     
    	for(ObjetA obj : listeObjetA)
    		str += obj.toString() ;
    	return str ;
    }
    En fait c’est là que mon problème se pose, j’ai fait des tests, et appeler la méthode toString() est relativement rapide tant que ma listObjetA ne contient que quelques dizaines d’ ObjetA mais, en ajoutant 2000 objetA à mon ObjetB, l’appel de cette méthode prend 10 bonnes secondes. C’est long, trop long !

    J’ai donc tenté de coder mes objets un peu différemment en serializant non pas une ArrayList mais directement mes ObjetA.
    Désormais lorsque j’appelle la méthode toString() de mes 2000 ObjetA :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //Code simplifié à l'extreme
    public String toString(){
     
            File fichier = new File(path);
    	if(fichier.length() > 0) {
    		ObjectInputStream in = new ObjectInputStream(
    				New BufferedInputStream(
    					new FileInputStream(fichier)));
    		while(true)
    			str += in.readObject().toString();
    		in.close() ;
    	}
    	return str;
    }
    De cette manière je lis le fichier en 3,5 secondes(c’est quand même long non ?) mais par contre à chaque fois que je réouvre un flux vers mon fichier pour ajouter un ObjetA, celui-ci est écrasé et ne contient que la dernière entrée.
    Je pourrais mettre tous mes ObjetA dans une ArrayList à l’ouverture du flux, ajouter l’objetA à insérer et repasser par une boucle pour serializer mes ObjetA.
    Mais dans ce cas le gain de performance à la lecture est perdu lors de l’écriture…
    Bref je ne sais pas comment faire.
    Existe-il un moyen pour ajouter un ObjetA à mon fichier sans que celui-ci soit écrasé ?
    Mes connaissances en Java(ainsi qu’en programmation) étant limitées je sollicite vos conseils et votre expérience afin de m’orienter sur la bonne voie(qui est d’ailleurs peut-être à l’opposé de la méthode que j’utilise)
    Merci.

  2. #2
    Membre émérite Avatar de herch
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    655
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2006
    Messages : 655
    Par défaut
    salut,

    quand tu as une chaîne de caractères à laquelle tu concatènes d'autres chaînes, il est FORTEMENT déconseillé d'utiliser des String, parce qu'à chaque concaténation, il y a création d'un nouveau objet String, il faut plutôt utiliser un StringBuilder

    plus d'explications sur la concaténation des String

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public String toString(){
           StringBuilder str = new StringBuilder();
    	for(ObjetA obj : listeObjetA)
    		str.append(obj.toString());
    	return str.toString();
    }
    dis nous s'il y a un changement dans le temps d'exécution

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5
    Par défaut
    Merci pour l'info herch!
    En effet les resutats sont probants.
    J'oscille entre 0,1 et 0,2 secondes en utilisant un StringBuilder pour parcourir mon ArrayList de 2000 objet.

    -->drhouse,
    Rien à voir avec des transactions cependant je regarderais sgbd (connais pas) cela pourrais m'être utile.
    Merci.

  4. #4
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    ne pas oublier le bouton svp

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 33
    Par défaut
    Citation Envoyé par WaamO Voir le message
    Rien à voir avec des transactions cependant je regarderais sgbd (connais pas) cela pourrais m'être utile.
    Merci.
    Le rapport avec les transactions c'est la fréquence avec laquelle tu vas faire des écritures sur le disque. Si dans ton programme tu fais des appels répétés à ta méthode d'ajout, tu feras autant d'écritures que d'ajouts.
    En définissant une notion de transaction dans ton programme, tu peux faire :
    - ajout
    - ajout
    - écriture disque
    plutôt que :
    - ajout
    - écriture disque
    - ajout
    - écriture disque

    Note que c'est intéressant dans le cas où tu effectues des ajouts groupés.

    Je serais curieux de connaître le temps d'exécution si tu ajoutes 2000 objets dans une boucle ?

    Sinon, sgbd c'est l'abréviation pour Système de Gestion de Base de Données. Il en existe des "embedded" qui ne nécessitent pas de client/serveur et qui sont bien utiles lorsque tu veux stocker de manière performante des volumes importants de données sans avoir à gérer les accès disque.

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5
    Par défaut
    Citation Envoyé par drhouse Voir le message
    Si dans ton programme tu fais des appels répétés à ta méthode d'ajout, tu feras autant d'écritures que d'ajouts.
    En fait l'appel de la méthode reste ponctuel, d'où la serialization à la volée.
    Merci pour les infos!

    Sinon à l'aide d'une boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    for(int i=0; i<2000; i++)
    {
            ObjetA obj = new ObjetA(/*PARAM*/);
            listObjetA.addObjetA(obj);
    }
    Il me faut 30 secondes pour sortir de la boucle.
    (9 millisecondes par serialization)

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 33
    Par défaut
    ok je comprends, merci pour la précision.

    si tu ne fais que rarement des ajouts, tu devrais garder ta String en cache et la recalculer lorsqu'il y a un ajout (d'ailleurs tu peux aussi garder le buffer, ça te permet de reconstruire la String de manière incrémentale).

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 33
    Par défaut
    En complément de la remarque sur les string, d'après ce que j'ai compris, tu serializes après chaque ajout. Donc si tu ajoutes 2000 objets, tu serializes 2000 fois, par conséquent, 2000 écritures de fichier. A mon avis, une bonne partie de ton problème de perfo doit venir de là : une écriture sur disque c'est couteux comparé à des opérations en mémoire.
    Tu devrais mettre en place un mécanisme qui te permet de serializer un nouvel objet sans tout réécrire, et éventuellement de grouper tes écritures lors des ajouts... tout cela fait penser à des transactions, et plutôt que de réinventer la roue, tu peux t'orienter vers un sgbd "java embedded". Par exemple, H2.

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

Discussions similaires

  1. [C++] - Lecture/ecriture d'une bmp
    Par Alice9 dans le forum C++
    Réponses: 2
    Dernier message: 13/04/2006, 19h59
  2. Problème de gestion d'une collection d'objet
    Par poolky dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 17/02/2006, 21h51
  3. [JDBC]lecture/ecriture dans une base de donnée
    Par tarik75 dans le forum JDBC
    Réponses: 7
    Dernier message: 30/06/2005, 12h42
  4. [Struts] <logic:iterate> sur une collection d objets c
    Par trax020 dans le forum Struts 1
    Réponses: 2
    Dernier message: 12/05/2005, 00h11
  5. [VB6] Sauvegarder une collection d'objets
    Par Sayagh dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 19/09/2003, 11h58

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