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

  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 : 40
    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
    Points : 4 240
    Points
    4 240
    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 sénior
    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
    Points : 23 190
    Points
    23 190
    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 chevronné
    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
    Points : 1 996
    Points
    1 996
    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 sénior
    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
    Points : 23 190
    Points
    23 190
    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 : 40
    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
    Points : 4 240
    Points
    4 240
    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 habitué 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
    Points : 131
    Points
    131
    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 averti
    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
    Points : 402
    Points
    402
    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

  8. #8
    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 : 40
    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
    Points : 4 240
    Points
    4 240
    Par défaut
    Bonjour,

    J'ai réussi à optimiser pas mal le code, je suis descendu en dessous des 1.5sec.
    Il me reste plus grand chose pour passer en dessous de la seconde (même si j'imagine que ça va être le plus dur).
    Alors j'ai suivi vos diverses recommandations :
    - utilisation de tableaux de char plutôt que de string.
    - parcours des tableaux de char à la mano
    - ne pas recréer inutilement des strings
    - etc

    Mais il reste un truc qui surement peut être optimisé :

    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
     
    public static List<char[]> splitString(char[] strOrigine, char sep, int deb, int fin) {
    	int precIndex = deb;
     
    	List<char[]> res = new ArrayList<char[]>(); 
    	for(int i = deb; i < fin ;i++) {
    		if (strOrigine[i] == sep) {
    			char[] newtab = new char[(i-precIndex)+1];
     
    			System.arraycopy(strOrigine, precIndex, newtab, 0, i-precIndex);
    			res.add(newtab); 
    			precIndex = i+1;
    		}
    	}
     
    	return res;
    }
    Notamment la création de nombreux tableaux de char pour identifier chacun des nouveaux mots (avec ce que ça coute : allocation mémoire, recopie des caractères, et stockage dans une liste).
    Y'a pas un moyen plus simple de créer d'autres tableaux de char à partir d'un grand tableau ?
    (un peu à la manière de C ou C++ avec la notion de pointeur et caractère de fin de tableau)

    Merci en tout cas de vos conseils.

  9. #9
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Perso je ne pense pas que le choix des char[] soit une bonne idée...


    Pourrais-tu fournir le code complet du traitement (avec la lecture du fichier) ainsi qu'un exemple de données...


    a++

  10. #10
    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 : 40
    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
    Points : 4 240
    Points
    4 240
    Par défaut
    Une ligne du fichier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    2;37;1325;0{};1{13=26.662069947305138#11=49.0#1=1325#14=19.59496606987986#10=22.7904361186905#12=0.0#};2{};3{};4{13=23.549652596208563#11=49.0#1=1325#14=27.506890753242686#10=23.918230842566686#12=0.0#};5{};6{};7{13=24.637932697545665#11=49.0#1=1325#14=25.312906494304652#10=33.02821200009616#12=0.0#};8{51=the¤143¤console¤34¤script¤53¤If¤59¤the newversion.script¤52¤on¤57¤teamlog¤46¤there¤41¤problems in¤46¤tata¤56¤inconsistency¤48¤Edit and correct¤46¤toto¤55¤data¤49¤and the opening¤49¤line¤57¤is¤104¤reported¤46¤in¤46¤any¤90¤process is aborted.¤47¤titi¤56¤number¤45¤#53=the¤146¤console¤50¤script¤51¤If¤57¤the newversion.script¤52¤on¤42¤teamlog¤48¤there¤46¤problems in¤52¤inconsistency¤46¤tata¤45¤Edit and correct¤45¤toto¤56¤data¤60¤and the opening¤42¤line¤48¤is¤99¤in¤56¤reported¤44¤any¤88¤process is aborted.¤51¤number¤57¤titi¤44¤#55=24.291320754716985#1=1325#50=the¤164¤console¤45¤script¤46¤the newversion.script¤49¤If¤58¤on¤56¤teamlog¤42¤there¤41¤problems in¤61¤Edit and correct¤34¤tata¤52¤inconsistency¤52¤toto¤45¤data¤59¤and the opening¤45¤line¤60¤is¤105¤in¤62¤reported¤39¤any¤71¤process is aborted.¤42¤titi¤55¤number¤42¤#52=the¤141¤console¤38¤script¤50¤the newversion.script¤55¤If¤33¤on¤46¤there¤61¤teamlog¤47¤problems in¤45¤tata¤53¤inconsistency¤43¤Edit and correct¤36¤toto¤60¤data¤49¤and the opening¤48¤line¤49¤is¤113¤in¤57¤reported¤54¤any¤111¤process is aborted.¤44¤titi¤46¤number¤46¤#56=the¤151¤console¤39¤script¤44¤the newversion.script¤38¤If¤47¤on¤47¤there¤45¤teamlog¤51¤problems in¤63¤Edit and correct¤59¤inconsistency¤49¤tata¤52¤toto¤51¤data¤52¤and the opening¤61¤line¤48¤is¤89¤reported¤45¤in¤49¤any¤87¤process is aborted.¤62¤titi¤50¤number¤46¤#54=the¤147¤console¤50¤script¤47¤If¤47¤the newversion.script¤46¤on¤31¤teamlog¤56¤there¤57¤problems in¤51¤inconsistency¤47¤Edit and correct¤66¤tata¤43¤toto¤49¤data¤59¤and the opening¤49¤line¤48¤is¤88¤in¤51¤reported¤50¤process is aborted.¤45¤any¤104¤titi¤44¤number¤50¤#};14{51=the¤153¤console¤57¤script¤45¤the newversion.script¤59¤If¤36¤on¤57¤teamlog¤56¤there¤50¤problems in¤46¤Edit and correct¤42¤tata¤49¤inconsistency¤51¤toto¤45¤data¤41¤and the opening¤40¤line¤63¤is¤110¤reported¤45¤in¤56¤any¤75¤process is aborted.¤50¤titi¤46¤number¤53¤#53=the¤145¤console¤58¤script¤49¤the newversion.script¤57¤If¤56¤on¤46¤teamlog¤52¤there¤46¤problems in¤55¤Edit and correct¤39¤inconsistency¤60¤tata¤50¤toto¤42¤data¤48¤and the opening¤58¤line¤44¤is¤103¤reported¤47¤in¤50¤any¤84¤process is aborted.¤43¤number¤47¤titi¤46¤#55=23.958490566037746#1=1325#50=the¤150¤console¤45¤script¤58¤If¤43¤the newversion.script¤53¤on¤48¤teamlog¤44¤there¤38¤problems in¤46¤tata¤51¤Edit and correct¤54¤inconsistency¤50¤toto¤45¤data¤56¤and the opening¤39¤line¤47¤is¤109¤in¤48¤reported¤50¤any¤104¤process is aborted.¤41¤titi¤52¤number¤54¤#52=the¤141¤console¤55¤script¤48¤If¤49¤the newversion.script¤52¤on¤44¤there¤51¤teamlog¤49¤problems in¤56¤tata¤47¤inconsistency¤43¤Edit and correct¤52¤toto¤43¤data¤45¤and the opening¤48¤line¤40¤is¤99¤in¤59¤reported¤57¤any¤100¤process is aborted.¤49¤titi¤44¤number¤54¤#56=the¤147¤console¤47¤script¤53¤If¤54¤the newversion.script¤43¤on¤49¤there¤50¤teamlog¤48¤problems in¤53¤tata¤57¤Edit and correct¤45¤inconsistency¤49¤toto¤50¤data¤39¤and the opening¤57¤line¤48¤is¤95¤in¤48¤reported¤52¤any¤98¤process is aborted.¤46¤number¤50¤titi¤47¤#54=the¤155¤console¤49¤script¤44¤the newversion.script¤37¤If¤56¤on¤63¤teamlog¤30¤there¤48¤problems in¤59¤inconsistency¤50¤tata¤43¤Edit and correct¤39¤toto¤50¤data¤57¤and the opening¤48¤line¤47¤is¤110¤reported¤56¤in¤39¤process is aborted.¤42¤any¤90¤titi¤57¤number¤56¤#};37{};
    Lecture du fichier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    while( (line = inbr.readLine()) != null) {		
    	SDDSequence seq = decodeLine(line.toCharArray());
    	listSeq.add(seq);
    }
    (dans le fichier il y en a environ 2000 comme ça)

    Analyse d'une ligne :

    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
     
    private static SDDSequence decodeLine(char[] p_line) {
    	SDDSequence resSequence = null;
    	int lnLine = p_line.length;
    	if (p_line != null && lnLine >=0) {	
    		resSequence = new SDDSequence();
    		List<Integer> listNoeud = new ArrayList<Integer>();
    		Map<Integer, SDDData> tabData = new HashMap<Integer, SDDData>();
     
    		List<char[]> listId = SDDData.splitString(p_line, ';', 0, lnLine);
     
    		int in = SDDData.getInteger(listId.get(0));
    		int out = SDDData.getInteger(listId.get(1));
    		int count = SDDData.getInteger(listId.get(2));
    		int listIdSize = listId.size();
    		for(int i = 3; i < listIdSize; i++) {
    			char[] param = listId.get(i);
    			int lnParam = param.length;
    			Integer idNoeud = null;
    			SDDData data = null;
    			int debParam = 0;
    			for(int ite = 0; ite < lnParam; ite++) {
    				if (param[ite] == '{') {
    					debParam = ite;
    					idNoeud = SDDData.getInteger(param, ite);
    					break;
    				}
    			}
    			for(int ite = lnParam-1; ite > debParam; ite--) {
    				if (param[ite] == '}') {
    					data = SDDData.makeData(param, debParam + 1, ite); 
    					break;
    				}
    			}
     
    			listNoeud.add(idNoeud);
    			if (data != null) {
    				tabData.put(idNoeud, data);
    			}
     
    		}
     
    		resSequence.setInOut(in, out);
    		resSequence.setTabNoeud(listNoeud, tabData);
    		resSequence.setCount(count);
     
    	}
     
    	return resSequence;
    }
    Analyse des paramètres :

    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
     
    public static SDDData makeData(char[] p_string, int deb, int fin) {
    	SDDData data = null;
     
    	if (p_string != null && p_string.length > 0) {
    		data = new SDDData();
    		//On découpe en morceau cle=valeur
     
    		List<char[]> listParam = splitString(p_string, '#', deb, fin); 
     
    		for(char[] iteParam : listParam) {
     
    			int ln = iteParam.length;
    			//On identifie le type de la valeur en fonction de la clé.
    			int indexOfEqual = -1;
    			for (int i = 0; i < ln; i++) {
    				if (iteParam[i] == '=') {
    					indexOfEqual = i;
    					break;
    				}
    			}
     
     
    			String keyStr = new String(iteParam, 0, indexOfEqual);
    			Integer keyInt = Integer.valueOf(keyStr);
    			char[] valueStr = new char[(ln - indexOfEqual)-1];
    			System.arraycopy(iteParam, indexOfEqual+1, valueStr, 0, (ln - indexOfEqual - 1));
     
    			switch(keyInt) {
    			case 1: 
    				Integer valueInt = getInteger(valueStr); 
    				data.m_ListData.put(keyInt, valueInt);
    				break;
     
    			case 2:
     
    				Double valueDou = Double.parseDouble(new String(valueStr));
    				data.m_ListData.put(keyInt, valueDou);
    				break;
     
    			case 3 :
    				Map<char[], Integer> listVariousParam = new HashMap<char[], Integer>();
     
    				List<char[]> testValue2 = splitString(valueStr, '¤');
    				int maxLn = testValue2.size();
     
    				for(int i = 0; i < maxLn; i+=2) {
    					listVariousParam.put(testValue2.get(i), getInteger(testValue2.get(i+1)) ); 
    				}
     
    				data.m_ListData.put(keyInt, listVariousParam);
    				break;
     
    			}
    		}
    	}
     
    	return data;
    }

    Le code de "mon split" :
    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
     
    public static List<char[]> splitString(char[] strOrigine, char sep, int deb, int fin) {
    	int precIndex = deb;
     
     
    	List<char[]> res = new ArrayList<char[]>(); 
    	for(int i = deb; i < fin ;i++) {
    		if (strOrigine[i] == sep) {
    			char[] newtab = new char[(i-precIndex)+1];
     
    			System.arraycopy(strOrigine, precIndex, newtab, 0, i-precIndex);
    			res.add(newtab); 
    		        precIndex = i+1;
    		}
    	}	
    	return res;
    }
    Donc voilà vous avez à peu près tout. J'ai essayer de simplifier au maximum le code présenté.

  11. #11
    Membre averti
    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
    Points : 402
    Points
    402
    Par défaut
    Je pense que tu peux encore faire mieux si tu utilise des byte[], la seule contrainte c'est qu'il faut que les caractère de ton fichiers soit encodé en ASCII ou ISO8859-1 (7 ou 8bit) t'a qu'à changer ta méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List<char[]> split(char[])
    ->
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List<byte[]>split(byte[])
    c'est plus bas niveau mais je pense que c'est le + optimum car ca va t'éviter de faire des appel a CharEncoder utiliser pr encoder des byte[] -> char[]
    a++

  12. #12
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    MrDuChnok > Il ne m'est toujours pas possible de tester ton code. Tant pis...

    hibour > Je ne pense pas que cette conversion soit très couteuse, par contre on manipule un type encore moins précis ce qui obligera par la suite encore plus de manipulation un code illisible pour pas grand chose !

    a++

  13. #13
    Membre chevronné
    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
    Points : 1 996
    Points
    1 996
    Par défaut
    Une meilleure alternative à splitString de MrDuChnok ???

    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
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
     
    public class Main {
     
    	/**
             * @param args
             */
    	public static void main(String[] args) {
    		String[] test = {"123#4#567890121345#67",
    				         "",
    				         "1",
    				         "#",
    				         "#1",
    				         "1#",
    				         "#1#",
    				         "2;37;1325;0{};1{13=26.662069947305138#11=49.0#1=1325#14=19.59496606987986#10=22.7904361186905#12=0.0#};2{};3{};4{13=23.549652596208563#11=49.0#1=1325#14=27.506890753242686#10=23.918230842566686#12=0.0#};5{};6{};7{13=24.637932697545665#11=49.0#1=1325#14=25.312906494304652#10=33.02821200009616#12=0.0#};8{51=the¤143¤console¤34¤script¤53¤If¤59¤the newversion.script¤52¤on¤57¤teamlog¤46¤there¤41¤problems in¤46¤tata¤56¤inconsistency¤48¤Edit and correct¤46¤toto¤55¤data¤49¤and the opening¤49¤line¤57¤is¤104¤reported¤46¤in¤46¤any¤90¤process is aborted.¤47¤titi¤56¤number¤45¤#53=the¤146¤console¤50¤script¤51¤If¤57¤the newversion.script¤52¤on¤42¤teamlog¤48¤there¤46¤problems in¤52¤inconsistency¤46¤tata¤45¤Edit and correct¤45¤toto¤56¤data¤60¤and the opening¤42¤line¤48¤is¤99¤in¤56¤reported¤44¤any¤88¤process is aborted.¤51¤number¤57¤titi¤44¤#55=24.291320754716985#1=1325#50=the¤164¤console¤45¤script¤46¤the newversion.script¤49¤If¤58¤on¤56¤teamlog¤42¤there¤41¤problems in¤61¤Edit and correct¤34¤tata¤52¤inconsistency¤52¤toto¤45¤data¤59¤and the opening¤45¤line¤60¤is¤105¤in¤62¤reported¤39¤any¤71¤process is aborted.¤42¤titi¤55¤number¤42¤#52=the¤141¤console¤38¤script¤50¤the newversion.script¤55¤If¤33¤on¤46¤there¤61¤teamlog¤47¤problems in¤45¤tata¤53¤inconsistency¤43¤Edit and correct¤36¤toto¤60¤data¤49¤and the opening¤48¤line¤49¤is¤113¤in¤57¤reported¤54¤any¤111¤process is aborted.¤44¤titi¤46¤number¤46¤#56=the¤151¤console¤39¤script¤44¤the newversion.script¤38¤If¤47¤on¤47¤there¤45¤teamlog¤51¤problems in¤63¤Edit and correct¤59¤inconsistency¤49¤tata¤52¤toto¤51¤data¤52¤and the opening¤61¤line¤48¤is¤89¤reported¤45¤in¤49¤any¤87¤process is aborted.¤62¤titi¤50¤number¤46¤#54=the¤147¤console¤50¤script¤47¤If¤47¤the newversion.script¤46¤on¤31¤teamlog¤56¤there¤57¤problems in¤51¤inconsistency¤47¤Edit and correct¤66¤tata¤43¤toto¤49¤data¤59¤and the opening¤49¤line¤48¤is¤88¤in¤51¤reported¤50¤process is aborted.¤45¤any¤104¤titi¤44¤number¤50¤#};14{51=the¤153¤console¤57¤script¤45¤the newversion.script¤59¤If¤36¤on¤57¤teamlog¤56¤there¤50¤problems in¤46¤Edit and correct¤42¤tata¤49¤inconsistency¤51¤toto¤45¤data¤41¤and the opening¤40¤line¤63¤is¤110¤reported¤45¤in¤56¤any¤75¤process is aborted.¤50¤titi¤46¤number¤53¤#53=the¤145¤console¤58¤script¤49¤the newversion.script¤57¤If¤56¤on¤46¤teamlog¤52¤there¤46¤problems in¤55¤Edit and correct¤39¤inconsistency¤60¤tata¤50¤toto¤42¤data¤48¤and the opening¤58¤line¤44¤is¤103¤reported¤47¤in¤50¤any¤84¤process is aborted.¤43¤number¤47¤titi¤46¤#55=23.958490566037746#1=1325#50=the¤150¤console¤45¤script¤58¤If¤43¤the newversion.script¤53¤on¤48¤teamlog¤44¤there¤38¤problems in¤46¤tata¤51¤Edit and correct¤54¤inconsistency¤50¤toto¤45¤data¤56¤and the opening¤39¤line¤47¤is¤109¤in¤48¤reported¤50¤any¤104¤process is aborted.¤41¤titi¤52¤number¤54¤#52=the¤141¤console¤55¤script¤48¤If¤49¤the newversion.script¤52¤on¤44¤there¤51¤teamlog¤49¤problems in¤56¤tata¤47¤inconsistency¤43¤Edit and correct¤52¤toto¤43¤data¤45¤and the opening¤48¤line¤40¤is¤99¤in¤59¤reported¤57¤any¤100¤process is aborted.¤49¤titi¤44¤number¤54¤#56=the¤147¤console¤47¤script¤53¤If¤54¤the newversion.script¤43¤on¤49¤there¤50¤teamlog¤48¤problems in¤53¤tata¤57¤Edit and correct¤45¤inconsistency¤49¤toto¤50¤data¤39¤and the opening¤57¤line¤48¤is¤95¤in¤48¤reported¤52¤any¤98¤process is aborted.¤46¤number¤50¤titi¤47¤#54=the¤155¤console¤49¤script¤44¤the newversion.script¤37¤If¤56¤on¤63¤teamlog¤30¤there¤48¤problems in¤59¤inconsistency¤50¤tata¤43¤Edit and correct¤39¤toto¤50¤data¤57¤and the opening¤48¤line¤47¤is¤110¤reported¤56¤in¤39¤process is aborted.¤42¤any¤90¤titi¤57¤number¤56¤#};37{};"};
     
    		final StringBuffer result = new StringBuffer();
    		for (String s : test) {
    			result.setLength(0);
    			for (Iterator<CharSequence> iter = splitString(s, '#', 0, s.length());
    		     	iter.hasNext();){
    				CharSequence csq = iter.next();
    				result.append(csq);				
    			}
    			assert(s.replace("#", "").equals(result));
    			System.out.println("Test: " + s + " >> " + result);
    		}
    	}
     
    	public static Iterator<CharSequence> splitString(final CharSequence strOrigine, final char sep, final int deb, final int fin) {
    		if (deb < 0) {
    			throw new StringIndexOutOfBoundsException(deb);
    		}
    		if (fin < 0 || fin > strOrigine.length()) {
    			throw new StringIndexOutOfBoundsException(fin);
    		}
    		if (deb > fin) {
    			throw new StringIndexOutOfBoundsException("deb > fin");
    		}
     
    		final Iterator<CharSequence> iter = new Iterator<CharSequence>() {
     
    			private int startIndex = deb;
    			private int currentIndex = deb;
    			private int endIndex = deb;
     
    			public boolean hasNext() {
    				if (currentIndex < fin) {
    					startIndex = currentIndex;
    					while (currentIndex < fin) {
    						if (strOrigine.charAt(currentIndex) == sep) {
    							endIndex = currentIndex;
    							++currentIndex;
    							return true;
    						}
    						++currentIndex;
    					}
    					endIndex = fin;
    					return true;
    				}
    				return false;
    			}
     
    			public CharSequence next() {
    				final CharSequence charSeq = new CharSequence() {
     
    					public char charAt(int index) {
    						// TODO Check OutOfBoundException of index					
    						return strOrigine.charAt(startIndex+index);
    					}
     
    					public int length() {
    						final int len = endIndex-startIndex; 
    						return len;
    					}
     
    					public CharSequence subSequence(int start, int end) {
    						// TODO Check OutOfBoundException of start and end
    						final StringBuilder sb = new StringBuilder(this.length());
    						final int offset = startIndex+ start;
    						sb.append(strOrigine, offset, this.length());
    						return sb;
    					}
     
    				};
    				return charSeq;
    			}
     
    			public void remove() {
    				throw new UnsupportedOperationException();				
    			}
     
    		};
    		return iter;
    	}
    }

  14. #14
    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 : 40
    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
    Points : 4 240
    Points
    4 240
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    hibour > Je ne pense pas que cette conversion soit très couteuse, par contre on manipule un type encore moins précis ce qui obligera par la suite encore plus de manipulation un code illisible pour pas grand chose !
    Je pense également la même chose que toi. J'ai pu tester la différence entre le passage String -> char[], j'ai vu un gain de performance (surement due à ma mauvaise utilisation de la classe String).

    MrDuChnok > Il ne m'est toujours pas possible de tester ton code. Tant pis...
    Ouais, je comprends bien que c'est pas facile d'aider si je fournis pas toutes les pièces du puzzles... si j'ai le temps, je vais essayer de faire une classe compilable.

    Une meilleure alternative à splitString de MrDuChnok ???
    J'essaye de suite et je te tiens au courant.

  15. #15
    Membre averti
    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
    Points : 402
    Points
    402
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    hibour > Je ne pense pas que cette conversion soit très couteuse, par contre on manipule un type encore moins précis ce qui obligera par la suite encore plus de manipulation un code illisible pour pas grand chose !
    a++
    Je suis d'accord que le code va être plus compliqué à maintenir mais bon on sait que optimisation et généricité en rime pas ensemble. Il faut trouver un compromis entre les 2 et ce n'est pas toujours facile.. En tout cas byte c'est le type de base qu'un InputStream lit donc c'est le plus rapide je pense.

    a++

  16. #16
    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 : 40
    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
    Points : 4 240
    Points
    4 240
    Par défaut
    Oui, mais là ce qui est bloquant, c'est pas la lecture du fichier, plutôt le traitement des données. Du coup, à partir du moment où on manipule des types primitifs, je pense que c'est optimal, donc traiter du byte ou du char, ça revient à la même chose.

    @jowo ; j'ai testé ton code, et il fonctionne bien, mise à part une coquille dans le subSequence, mais rien de méchant. Par contre, je perds un peu en performance... Mais cette façon de faire m'a donné des idées d'améliorations probables. merci.

  17. #17
    Membre averti
    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
    Points : 402
    Points
    402
    Par défaut
    Oui c'est clair que la lecture du fichier ce n'est pas le goulot d'étranglement dans ton programme. pour optimiser encore ton code essai de fusionner les 2 boucles
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    for(int ite = 0; ite < lnParam; ite++) {
    				if (param[ite] == '{') {
    					debParam = ite;
    					idNoeud = SDDData.getInteger(param, ite);
    					break;
    				}
    			}
    			for(int ite = lnParam-1; ite > debParam; ite--) {
    				if (param[ite] == '}') {
    					data = SDDData.makeData(param, debParam + 1, ite); 
    					break;
    				}
    			}
    tu peux aussi éliminer certain new qui sont couteux. comme celui que tu fait pour avoir un int a partir de char[]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    String keyStr = new String(iteParam, 0, indexOfEqual);
    			Integer keyInt = Integer.valueOf(keyStr);
    tu peux faire une méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    static int valueOf(char[] str, int off, int len) {
    int sum = 0;
    for(int i = off, n = off + len; i < n; i++)
     sum += sum*10 + (str[i] - '0');
    return sum;
    }
    voila une piste
    a++

  18. #18
    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 : 40
    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
    Points : 4 240
    Points
    4 240
    Par défaut
    @propos des boucles optimisables, je pense qu'elles le sont déjà car :
    - le caractère '{' est susceptible de se trouver dans les 5 premiers caractères
    - le caractère '}' est susceptible de se trouver dans les 5 derniers caractères.
    La ligne peut faire des centaines (voir des milliers de caractères), alors autant commencer par le debut pour trouver '{', et par la fin pour trouver '}'.
    Enfin c'est ce que je pense...

    concernant tes deux autres remarques, elles étaient déjà en pratique, mais merci quand même.

    Par contre pour passer d'un String (ou d'un char[]) à un Double, qu'est ce qui est le mieux ?

  19. #19
    Membre averti
    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
    Points : 402
    Points
    402
    Par défaut
    Citation Envoyé par MrDuChnok Voir le message
    Par contre pour passer d'un String (ou d'un char[]) à un Double, qu'est ce qui est le mieux ?
    Je pense que Double.valueOf(String) est deja bien.

  20. #20
    Membre habitué 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
    Points : 131
    Points
    131
    Par défaut
    Si tu veux optimiser: ne lit pas plusieurs fois ta chaine ! Il faut voir l'algorithme dans sa globalité et non pas chercher le premier délimiteur en parcourant tout, chercher le deuxième à l'intérieur des chaines en parcourant tout à nouveau, etc...
    Le code sera moins lisible mais plus efficace (ce qui est souvent le cas !).

    Peux tu expliquer comment tu lis ta ligne ?
    • le premier délimiteur est le ; ?
    • ensuite on a un entier et une partie optionnelle entre {} ?
    • dans la partie {}, le délimiteur suivant est le # ?
    • dans chaque partie entre # on a un entier, puis =, puis
      • soit un nombre,
      • soit des chaines et entiers séparés par des ¤

    Qu'est ce que tu veux à la fin ???

Discussions similaires

  1. Performance : optimisation de lecture fichier
    Par Graffito dans le forum Développement Windows
    Réponses: 0
    Dernier message: 12/06/2010, 01h36
  2. Optimisation lecture fichier > 3 Mo
    Par Sebastien_INR59 dans le forum Entrée/Sortie
    Réponses: 9
    Dernier message: 21/11/2007, 02h34
  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, 13h46
  4. optimiser lecture fichier image
    Par cheho dans le forum C++
    Réponses: 17
    Dernier message: 15/09/2006, 15h14

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