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

Entrée/Sortie Java Discussion :

[Lecture Fichier] Optimisation du parseur


Sujet :

Entrée/Sortie Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur
    Avatar de MrDuChnok
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2002
    Messages
    2 112
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 112
    Par défaut [Lecture Fichier] Optimisation du parseur
    Bonjour,

    J'aurai besoin de conseils vis à vis de l'optimisation de code.
    Je dois lire un "gros" fichier texte d'environ 5Mo. Il est constitué d'environ 2000 lignes, dont certaines assez longues (> 4000 caractères).
    Sur chacune de ces lignes sont encodées tous un tas de paramètres qui doivent être lus dans l'ordre d'écriture.
    Sur une ligne, on va trouver des paramètres principaux séparés par un premier délimiteur. Pour chacun des paramètres principaux, il y a des paramètres secondaires séparées par un deuxième délimiteur. Et enfin pour chacun des paramètre secondaire, il y a des paramètres tertiaires séparés par un autre délimiteur.

    Actuellement voici mon algo de lecture :
    Pour tout le fichier :
    Je lis une ligne.
    J'utilise le split pour découper selon le 1 délimiteur.
    Pour chacun des blocs obtenus, je redécoupe avec split pour le 2ème délimiteur.
    Pour chacun des sous blocs, je (re)redécoupe avec split pour le 3ème délimiteur.


    Dans un premier temps j'ai utilisé le String.split(). Après quelques recherches, je me suis rendu compte qu'il étais plus intéressant de précompiler le pattern de l'expression régulière et de la réutiliser à chaque fois (Pattern).

    Maintenant je m'aperçois, via JProfiler que c'est cette dernière méthode qui est la plus gourmande dans mon algorithme. ça met environ 5sec à lire mon fichier, j'aimerai que ça descendre en dessous de la seconde, si c'est possible.
    Avez vous des conseils d'optimisations à me donner ? (threader la lecture, changer la méthode de split, améliorer les expressions régulières, etc)
    Voir même changer le format du fichier d'entrée si c'est vraiment pas jouable.

  2. #2
    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 MrDuChnok Voir le message
    Dans un premier temps j'ai utilisé le String.split(). Après quelques recherches, je me suis rendu compte qu'il étais plus intéressant de précompiler le pattern de l'expression régulière et de la réutiliser à chaque fois (Pattern).
    En effet en règle général la création du Pattern est assez couteuse, alors que son utilisation l'est nettement moins.

    Citation Envoyé par MrDuChnok Voir le message
    Avez vous des conseils d'optimisations à me donner ? (threader la lecture, changer la méthode de split, améliorer les expressions régulières, etc)
    Voir même changer le format du fichier d'entrée si c'est vraiment pas jouable.
    Le threading apportera un amélioration seulement si tu es sur un bi-processeur ou un bi-coeur ou plus... et encore cela dépend car tu auras un surcoût lié à la synchronisation...


    Pour t'aider davantage il faudrait avoir ton code et un échantillon du fichier...

    a++

  3. #3
    Membre Expert
    Homme Profil pro
    Dév. Java & C#
    Inscrit en
    Octobre 2002
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dév. Java & C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 414
    Par défaut
    Bonjour,

    Une voie d'amélioration est de ne pas utiliser de la classe String durant le traitement de ton fichier.

    Je travaille actuellement sur un projet (Java 1.4) où le traitement se fait sur des fichiers texte > 100Mo avec des lignes d'environ 200 caractères. Le fichier parsé produit un autre fichier ~5Mo.

    Je n'utilise que les classes StringBuffer, CharSequence et pour certains points les expression rationnelles. Je suis en dessous des 3s de traitement.

    Le point de départ de mon idée de ne pas utiliser la Classe String est dû au fait que c'est une classe immuable. La lecture d'un fichier de 100Mo va générer la même quantité de données le GC devra libérer.

    Je ne sais pas si la base de réflexion est correcte. Je n'ai pas fait de mesure donc tout est subjectif.

  4. #4
    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
    Citation Envoyé par jowo Voir le message
    Le point de départ de mon idée de ne pas utiliser la Classe String est dû au fait que c'est une classe immuable. La lecture d'un fichier de 100Mo va générer la même quantité de données le GC devra libérer.
    La classe String en elle même n'est pas un problème (d'ailleurs lorsque tu manipules des CharSequence il y a de forte chance que tu manipules en réalité des String). Il faut juste prendre conscience qu'il ne faut pas concaténer des String dans une boucle (voir la FAQ : Comment concatener des chaînes de caractères ?)

    a++

  5. #5
    Rédacteur
    Avatar de MrDuChnok
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2002
    Messages
    2 112
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 112
    Par défaut
    voilà le goulot d'étranglement principale :

    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
     
    String[] listParam = patternDiese.split(p_string); //p_string.split("#");
    for(String iteParam : listParam) {
    	//On identifie le type de la valeur en fonction de la clé.
    	int indexOfEqual = iteParam.indexOf("=");
    	String keyStr = iteParam.substring(0, indexOfEqual);
    	Integer keyInt = Integer.valueOf(keyStr);
    	String valueStr = iteParam.substring(indexOfEqual + 1, iteParam.length() );
    	switch(keyInt) {
     
    	case 1:
     
    		Double valueDou = Double.valueOf(valueStr);
    		data.m_ListData.put(keyInt, valueDou);
    		break;
     
    	case 2 :
    		Map<String, Integer> listVariousParam = new HashMap<String, Integer>();
     
    		String[] listStrVariousParam = patternSep.split(valueStr);//  valueStr.split("¤");
    		int indexOfFleche = -1;
    		for(String variousParam : listStrVariousParam) {
    			indexOfFleche = variousParam.indexOf("->");
    		       String keyStrVariousParam = variousParam.substring(0, indexOfFleche);
     
    			String valueStrVariousParam = variousParam.substring(indexOfFleche + 2, variousParam.length() );
     
    			listVariousParam.put(keyStrVariousParam, Integer.valueOf(valueStrVariousParam));
    		}
     
    		data.m_ListData.put(keyInt, listVariousParam);
    		break;
     
     
    	}
    }
    Donc voilà où j'en suis. Je vais essayer d'explorer la piste des CharSequence peut être...

  6. #6
    Membre éprouvé Avatar de jean.2edi
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juillet 2008
    Messages : 106
    Par défaut
    Si ton délimiteur est simple, il vaudrait mieux éviter les expressions rationnelles et utiliser des recherches de chaînes ou caractère (ton # et ton ¤).

    Ensuite, il faut effectivement éviter de fabriquer des chaines temporaires avec les morceaux de ce que tu as trouvé : gère plutôt une chaine de départ (ta ligne) sous forme de String ou CharSequence ou tableau de caractères ou de byte et des indices de début / fin.

    Ce sera bien moins lisible mais plus efficace à mon avis...

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Par défaut
    Salut
    La méthode String.split(regex) qui utilise la classe Pattern est moins performante que celle de StringUtils.split() de apache (commons-lang) qui utilise StringTokenizer.
    Cdlt

Discussions similaires

  1. Performance : optimisation de lecture fichier
    Par Graffito dans le forum Développement Windows
    Réponses: 0
    Dernier message: 12/06/2010, 00h36
  2. Optimisation lecture fichier > 3 Mo
    Par Sebastien_INR59 dans le forum Entrée/Sortie
    Réponses: 9
    Dernier message: 21/11/2007, 01h34
  3. Optimisation lecture fichier via un shell script
    Par macleod dans le forum Shell et commandes GNU
    Réponses: 5
    Dernier message: 31/07/2007, 12h46
  4. optimiser lecture fichier image
    Par cheho dans le forum C++
    Réponses: 17
    Dernier message: 15/09/2006, 14h14

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