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 :

[Stratégie] Réduire le temps de lecture de fichier et serialisation


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    386
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 386
    Par défaut [Stratégie] Réduire le temps de lecture de fichier et serialisation
    Bonjour à tous! Je vais essayer d'être la plus précise possible : J'ai des fichiers .txt que je dois parcourir, lire, et avec les informations lues, je dois construire des objets et les serialiser ensuite. J'ai notament un fichier qui fait 54 000 lignes. Pour situer le contexte, ce fichier est l'enregistrement des commandes. Chaque ligne représente la vente d'un lot (ou d'une partie de lot) pour un article donnée et pour une commande donnée. Je dois donc créer ces objets lots, articles et commande. Une commande contiendra donc un ou plusieurs articles, et un article un ou plusieurs lots. Donc je lis mon fichier avec un FileReader et je le parcours avec un BufferedReader.
    Le probleme c'est que les lignes concernant une meme commande ne sont pas les unes à la suite des autres, elles sont dispersées dans le fichier. Ma méthode :
    Je lis ma ligne avec mon premier bufferedReader. Je memorise la ReferenceCommande de cette ligne dans une variable. Je vais ranger toutes les lignes concernant cette commande dans une hashmap. pour cela je parcour tout le fichier avec un deuxieme BufferedReader (et un deuxieme FileReader). Une fois la fin du fichier atteint j'ai donc recuperé toutes mes lignes pour cette commande. Je ferme donc les 2eme BufferedReader et FileReader, et je construit mes Lots et Articles, et ma Commande pour finir, que je range dans une HashMap qui contiendra donc toutes les commandes de ce fichier. Puis mon premier BufferedReader passe a la ligne suivante, je regarde si la referenceCommande de cette ligne n'et pas une commande deja traitée (j'ai mémorisé dans un ArrayList toutes les refCommandes déjà traité) et si ce n'est donc pas le cas, je recommence le traitement.
    Probleme, avec 54 000 lignes, cette methode prendrai plus de 24h... en effet arrivé environ à la 22 000 ligne, le programme ne traite environ qu'une ligne toutes les 2 secondes. Plus le programme avance dans les lignes traitées, plus il ralenti.
    A chaque commande toutes mes variables sont "vidées" excepté le HashMap qui contient toutes les commandes. Je ne sais pas tres bien comment fonctionne les BufferedReader et les FileReader, donc je ne sais pas si ce sont eux (les premiers, ceux qui restent ouverts) qui ralentissent mon application, ou bien uniquement le HashMap qui contient toutes mes commandes.
    Bref je cherche un moyen d'optimiser le temps d'execution, si quelqu'un a une idée?? Merci d'avoir lu jusqu'au bout

  2. #2
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2007
    Messages
    387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2007
    Messages : 387
    Par défaut
    Tout d'abord, ne t'attends ps à avoir quelquechose qui prenne 2mn à l'exécution, car tes données sont trop "lourdes".

    D'après ce que j'ai compris, tu recherche une commande, avec son id, tu recherches toutes les lignes concernant cette commande, et tu stocks temporairement tout ca dans une hashmap, et une fois toutes les données parcourues, tu mets ta hashmap temporaire dans une hashmap principale.

    Est-ce bien cela ?

  3. #3
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par kahya Voir le message
    Bref je cherche un moyen d'optimiser le temps d'execution, si quelqu'un a une idée?? Merci d'avoir lu jusqu'au bout
    En même temps sans la moindre ligne de code cela risque d'être difficile...


    Mais concernant on algo, je ne comprend pas ce qui t'empêche de faire une seule lecture :
    1. Tu lis une ligne et tu récupères son "ReferenceCommande".
    2. Tu utilises une Map qui contiendra toutes les "ReferenceCommande". Si elle n'est pas présente tu la crées et tu l'ajoutes, sinon tu la récupère.
    3. Tu crées le Lot/Article correspondant à cette ligne
    4. Tu passes à la ligne suivante et tu recommence


    a++

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    386
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 386
    Par défaut
    Je n'ai pas bien compri ton 2), mais pour le reste, je ne construit pas un article a chaque ligne. En fait il me faut recuperer
    1) dans le fichier, toutes les lignes qui concerne la commande en cours, je les range dans la Map maCommande (et ça pour toutes les commandes)
    2) dans cette map maCommande, je recupere toutes les lignes de mon article en cours, je les range dans la Map monArticle (et ça pour chaque article)
    3) une fois que j'ai isolé toutes les ligne de l'Aarticle en cours de la Commande en cours, je construit donc un lot, avec chacune de ces lignes. Une fois que j'ai construit mes lots avec toutes les lignes de ma Map article, je peux donc construire mon Article, qui contiendra ces lots dans un tableau. Et une fois que j'ai constuit tout mes articles (avec leurs lots) Je peux constuire ma commande qui contient tout ses articles (qui contiennent tout leurs lots).
    Voila exactement comment ça se passe. Pour le code je veux bien mais je ne sais pas trop quel morceau mettre, ou alors je le met tout mais c'est long.

  5. #5
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Le problème c'est que cela a l'air assez complexe et que sans code ni exemple des données traitées cela va être impossible de t'aider...


    a++

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    386
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 386
    Par défaut
    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    public void lireFichier(String fichier) 
    	{
    		ArrayList dejaTraite = new ArrayList();
    		String CommandeActuelle = "";
    		ArrayList CommandeEnCourLIST = new ArrayList();
     
    		separateur = OrdreChamp.getSeparateur(ImportInterface.PathFichierOrdreChampClient, new ArrayList());
    		ordre = OrdreChamp.remplirOrdre(ImportInterface.PathFichierOrdreChampCommandeClient, new ArrayList(), new ArrayList());
    		try 
    		{
    			monLecteurFichier = new FileReader(fichier);
    			tampon = new BufferedReader(monLecteurFichier);
    			int cptLigne = 0;
    			while (true) 
    			{
    				BufferedReader tampon2 = null;
    				FileReader monLecteurFichier2 = new FileReader(fichier);
    				String ligne = tampon.readLine();
    				if (ligne == null)
    					break;
    				HashMap nouvelleLigneMAP = decouperLigne(ligne);
    //				Si on ne l'a pas encore traité
    				if (!dejaTraite.contains(nouvelleLigneMAP.get("H").toString()))
    				{
    					if (nouvelleLigneMAP.get("H").toString().compareToIgnoreCase("") != 0)
    					{
    						CommandeActuelle = nouvelleLigneMAP.get("H").toString();
    						dejaTraite.add(nouvelleLigneMAP.get("H").toString());
    						CommandeEnCourLIST = new ArrayList();
    					}
    					else
    					{
    						itéCommande ++;
    						CommandeActuelle = "gene" + String.valueOf(itéCommande);
    						dejaTraite.add("gene" + String.valueOf(itéCommande));
    						CommandeEnCourLIST = new ArrayList();
    						CommandeEnCourLIST.add(nouvelleLigneMAP);
    					}
     
    					cptCommande = 0;
    					tampon2 = new BufferedReader(monLecteurFichier2);
    					while (true) 
    					{
    						HashMap maLigne2Map = new HashMap();
    						String ligne2 = tampon2.readLine();
    						if (ligne2 == null)
    							break;
     
    						maLigne2Map = decouperLigne(ligne2);
    						if (maLigne2Map.get("H").toString().compareToIgnoreCase(CommandeActuelle)== 0)
    						{
    							CommandeEnCourLIST.add(maLigne2Map);
    							cptCommande ++;
    						}
    						cptLigne++;
    					}
    					tampon2.close();
    					monLecteurFichier2.close();
    					// On a notre AL avec toutes les lignes pour cette commande.
    					maCommandeEnCourLIST = new ArrayList(CommandeEnCourLIST);
    					while (maCommandeEnCourLIST.size()>0)
    					{
    						monArticleEnCourLIST = isolerArticle ();
    						tempMonArticleEnCourLIST = new ArrayList(monArticleEnCourLIST);
    						while (tempMonArticleEnCourLIST.size()>0)
    						{
    							construireLot ();
    							indiceLot ++;	
    						}
    						construireArticle();
    					}
    					construireCommande(CommandeEnCourLIST);
    				}
    			}
    		}
    nouvelleLigneMAP c'est une Map qui contient toute ma ligne "découpée". Par exemple nouvelleLigneMAP.get("H") renvoi ce qu'il y a dans la colone H sur ma ligne en cours, si on ouvre le fichier contenant les données avec Excell. Et c'est donc la méthode decouperLigne qui se charge de créer cette Map nouvelleLigneMap.
    Voila c'est le code qui fait le traitement, dites moi si vous voulez aussi le code des methodes construireLot construireCommande etc...

  7. #7
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2007
    Messages
    387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2007
    Messages : 387
    Par défaut
    Je pense que le raisonnement est bon, rien à optimiser la dessus.

    Le problème est qu'un élément du code pourrait tout ralentir (par exemple, un oubli de destruction qui te prendrais de la mémoire).

    C'est le problème de gérer des bases de données relativement importantes et de faire des traitements lourds dessus.

    Car là, si tu as 1000 commandes différentes, tu vas parcourir au moins 1000 fois ta table, ça prend déjà pas mal de temps.


    Donc je pense qu'il serait plus simple que tu parcours une seule fois ta liste, tu la ranges dans une List, une fois cette liste remplie, tu la trie (méthode Collections.sort(l)).

    Comme ca, une fois que tu auras trouvée une nouvelle commande, tu fais list.remove(nb).

    Ce qui fait que plus ca va venir, et plus les traitements seront rapides.


    NB : ce n'est qu'une idée

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

Discussions similaires

  1. Réduire le temps de chargement des fichiers sons
    Par j-jorge dans le forum Audio
    Réponses: 6
    Dernier message: 08/10/2013, 19h41
  2. Lecture de fichier depuis répertoire "Temp"
    Par dubitoph dans le forum Langage
    Réponses: 2
    Dernier message: 06/05/2011, 10h48
  3. [XPATH 1.0] Temps de lecture d'un "gros" fichier XML
    Par Ikki_2504 dans le forum XSL/XSLT/XPATH
    Réponses: 10
    Dernier message: 14/01/2011, 18h27
  4. Temps total de lecture de fichiers depuis le disque dur
    Par Tesing dans le forum Composants
    Réponses: 1
    Dernier message: 05/12/2009, 20h14
  5. Réponses: 2
    Dernier message: 24/04/2007, 22h03

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