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

Langage Java Discussion :

Lenteur du read line


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 50
    Par défaut Recupération d'un flux sans process.getOuputStream.close()
    Salut a tous.
    Dans un programme java je dois faire tourner une appli extérieure.
    Je l'ai donc tester dans un projet test avant de l'insérer dans un projet deja en court.
    Dans mon main je lance deux threads qui récuperent les donnees de l'appli et les erreurs.
    Le temps total est de 130 ms a peu pres et le code marche impec.
    Cependant, lorsque je copie exactement le même code dans le vrai projet, le temps de traitement passe à 1 seconde.
    En fait, 1 seconde par chaine de caracteres et il doit en traiter 150..., donc un peu moins de 3 minutes...c'est beaucoup trop long.

    voici le code du thread :

    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
    public void run() {
            try {
                BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                String line = "";
                try {
                    while((line = reader.readLine()) != null) {
                        // Traitement court
                    }
                } finally {
                    reader.close();
                }
            } catch(IOException ioe) {
                ioe.printStackTrace();
            }
        }
    Apres quelques tests, il s'est avérer que le traitement le plus long est le readline (+ ou - une seconde).

    Savez vous d'ou vient un tel changement de temps entre deux codes identiques?

    Merci

  2. #2
    Expert confirmé
    Avatar de Baptiste Wicht
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    7 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2005
    Messages : 7 431
    Par défaut
    Est-ce que par hasard, tu n'aurais pas dans ton traitement :

    Une concaténation de String ?

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 50
    Par défaut
    non, juste un split et un ajout dans un vecteur

  4. #4
    Expert confirmé
    Avatar de Baptiste Wicht
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    7 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2005
    Messages : 7 431
    Par défaut
    Citation Envoyé par qdqdfqfdqdxcwcrzsdfw
    non, juste un split et un ajout dans un vecteur
    Tu employais aussi split dans ta version de test ?

    Je suis pas sûr de moi, mais comme split découpe une chaine de caractères en plusieurs, ca crée plusieurs objets. Comme la création d'objets est très couteuse, le fait de l'employer dans une boucle risque de demander beaucoup de temps.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 50
    Par défaut
    oui, les codes sont identiques

  6. #6
    Membre Expert
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Par défaut
    a priori c'est le producteur qui traîne à produire ...
    problème processus système?

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 50
    Par défaut
    Bon, je vous dois des excuses, le programme est aussi long dans l'un que dans l'autre...
    est-ce qu'il y aurait un moyen de le rendre plus rapide? (un changement dans la syntaxe par exemple)

  8. #8
    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 qdqdfqfdqdxcwcrzsdfw
    est-ce qu'il y aurait un moyen de le rendre plus rapide? (un changement dans la syntaxe par exemple)
    Déjà il faudrait qu'on ai le code en entier, car // Traitement court est très rapide chez moi


    Ensuite il faudrait savoir ce que fait le processus que tu lances, et sa durée d'exécution lorsque tu le lances "à la main" via la console...


    a++

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 50
    Par défaut
    La traitement court effectue un split d'une chaine de caracteres que lui renvoie le cgi. Le tableau de chaines obtenu est ajouté dans un vecteur, c'est tout.

    Bon, je viens de me rendre compte que c'est le cgi qui met 1 seconde a démarrer...

    C'est un programme qui traite des chaines de caracteres. J'ai testé en mode console la différence entre 150 messages traités et 1000, et le temps ne fait que doubler a peine.

    C'est surtout le lancement qui prend une seconde.

    Le probleme pourrait etre resolu si le thread ne bloquait pas sur le readline tant que je n'ai pas fait le process.getOutputStream().close(); dans le main

    Pour mieux m'exprimer, il faudrait que le process reste à l'ecoute de nouvelle chaine de caracteres, que je puisse récupérer celle qui ont été traitées sans faire le process.getOutputStream().close() (sinon le process se ferme et il faut le relancer, donc je perds une seconde)

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 50
    Par défaut
    Est ce quelqu'un a une idée?

  11. #11
    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 qdqdfqfdqdxcwcrzsdfw
    La traitement court effectue un split d'une chaine de caracteres que lui renvoie le cgi. Le tableau de chaines obtenu est ajouté dans un vecteur, c'est tout.
    Mais pourquoi ne pas donner le code ??? Il est confidentiel ou protégé par copyright ou quoi ???

    Comment veux-tu qu'on puisse t'aider si tu donnes les informations au compte-goutte ???

    Citation Envoyé par qdqdfqfdqdxcwcrzsdfw
    Bon, je viens de me rendre compte que c'est le cgi qui met 1 seconde a démarrer...

    C'est un programme qui traite des chaines de caracteres. J'ai testé en mode console la différence entre 150 messages traités et 1000, et le temps ne fait que doubler a peine.

    C'est surtout le lancement qui prend une seconde.
    C'est à dire ? Quel est son temps d'exécution lorsque tu le lances à la main ?
    Le temps double par rapport à quoi ? Tout cela reste assez flou...

    Citation Envoyé par qdqdfqfdqdxcwcrzsdfw
    Le probleme pourrait etre resolu si le thread ne bloquait pas sur le readline tant que je n'ai pas fait le process.getOutputStream().close(); dans le main

    Pour mieux m'exprimer, il faudrait que le process reste à l'ecoute de nouvelle chaine de caracteres, que je puisse récupérer celle qui ont été traitées sans faire le process.getOutputStream().close() (sinon le process se ferme et il faut le relancer, donc je perds une seconde)
    C'est à dire ? Comment fonctionne ton application externe ?
    Que produit-elle comme résultat ? A partir de quoi ??? Quel est la communication que tu veux avoir entre les deux appli ???

    C'est franchement difficile de t'aider avec un aperçu de code et si peu d'info...

    a++

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 50
    Par défaut
    Citation Envoyé par adiGuba
    Mais pourquoi ne pas donner le code ??? Il est confidentiel ou protégé par copyright ou quoi ???

    Comment veux-tu qu'on puisse t'aider si tu donnes les informations au compte-goutte ???
    Je suis en stage dans une entreprise qui bosse sur un concept innovant, j'ai pas envie d'en dévoiler trop...

    sinon, voila le code du traitement court :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    lalignesplit = line.split("[\\t]");
    result.add(lalignesplit);
    Je mets le code entier plus tard.
    De plus, je ne l'ai pas mis car je me suis aperçu que ce n'était pas ce traitement qui était lent, mais le lancement de la commande externe.



    Citation Envoyé par adiGuba
    C'est à dire ? Quel est son temps d'exécution lorsque tu le lances à la main ?
    Le temps double par rapport à quoi ? Tout cela reste assez flou...
    C'est à dire ? Comment fonctionne ton application externe ?

    Que produit-elle comme résultat ? A partir de quoi ??? Quel est la communication que tu veux avoir entre les deux appli ???

    C'est franchement difficile de t'aider avec un aperçu de code et si peu d'info...

    a++
    Ce programme effectue une operation sur des chaines de caracteres.
    J'ai fait le test avec 1 phrase : 1seconde
    Avec 150 : 1,5 s
    Avec 1000 : 2 s
    Donc on s'apercoit bient que le temps d'execution n'est pas proportionnel au nombre de messages.
    Conclusion : il met une seconde à "démarrer" (initialisation,...), plus quelques millisecondes pour traiter un message.

    La ligne de commande est comme ceci : echo 'J'aime les fraises' | programme. (dans le cas d'un seul message)
    Le programme renvoie chaque mot à sa racine => Je aimer le fraise

    Ce programme n'est qu'une partie des traitements effectués sur une chaine de caracteres.
    Avant de l'intégrer dans le projet final, je l'ai testé dans une petit projet contenant TestMain.java et ProcessThreads.java
    La premiere classe lance l'appli et les threads, la deuxieme récupère ce que renvoie l'appli externe

    TestMain.java
    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
     
    import java.io.BufferedOutputStream;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.util.Date;
    import java.util.Vector;
     
    import threads.ProcessThreads;
    public class TestMain {
    public static void main(String[] args) {
     
    		Runtime runtime = Runtime.getRuntime();
    		ProcessThreads lethread = null;
    		ProcessThreads errthread = null;
    		try {
    			Process process = runtime
    					.exec("programme");
    			lethread = new ProcessThreads(process, ProcessThreads.T_OUT_MODE);
    			errthread = new ProcessThreads(process, ProcessThreads.T_ERR_MODE);
    			lethread.start();
    			errthread.start();
    			for (int i = 0; i < 500; i++) {
    				process.getOutputStream().write(
    						("Test" + i).getBytes("ISO-8859-1"));
    				process.getOutputStream().write((" @@@ ").getBytes("ISO-8859-1"));//fait office de séparateur
     
    				process.getOutputStream().flush();
    			}
     
    			process.getOutputStream().close();
     
    			lethread.join();
    			errthread.join();
     
    			Vector<String[]> leresultat = lethread.getResult();
     
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    //affichage des resultats, pas tres important
    		System.out.println("done");
     
    		System.exit(0);*/
    	}
    }
    La classe ProcessThreads :

    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
     
    package com.onyme.engine.processors;
     
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.Date;
    import java.util.Vector;
     
    class ProcessThreads extends Thread {
    	public static final int T_OUT_MODE = 1;
     
    	public static final int T_ERR_MODE = 2;
     
    	private Process process;
     
    	private int mode = 0;
     
    	private Vector<String[]> result = new Vector<String[]>();
     
    	public ProcessThreads(Process p, int m) {
    		process = p;
    		mode = m;
    		if (mode == T_OUT_MODE)
    			this.setName("T-OUT");
    		if (mode == T_ERR_MODE)
    			this.setName("T-ERR");
    	}
     
    	public void run() {
    		try {
    			BufferedReader reader = null;
    			if (mode == T_OUT_MODE)
    				reader = new BufferedReader(new InputStreamReader(process
    						.getInputStream(), "ISO-8859-1"));
    			if (mode == T_ERR_MODE)
    				reader = new BufferedReader(new InputStreamReader(process
    						.getErrorStream(), "ISO-8859-1"));
     
    			String line = "";
    			String[] lalignesplit = null;
     
    			try {
    				while ((line = reader.readLine()) != null) {
    					if (mode == T_OUT_MODE) {
    						lalignesplit = line.split("[\\t]");
    						result.add(lalignesplit);
    					}
    					if (mode == T_ERR_MODE) {
    						// System.out.println("ERR:"+line);
    						// lalignesplit = (new String(line)).split("[\\W]");
    					}
    				}
    			} finally {
    				reader.close();
    			}
    		} catch (IOException ioe) {
    			ioe.printStackTrace();
    		}
    	}
     
    	public Vector<String[]> getResult() {
    		return result;
    	}
     
    	public void setResult(Vector<String[]> result) {
    		this.result = result;
    	}
     
    }
    Dans le cas de cette appli tout va bien : quand le for du testmain.java est fini, on fait un process.getOutputStream.close() qui permet aux threads de récupérer les résultats.

    Par contre, le projet final consiste en une suite séquentielle de traitements de ce type.
    Cette partie n'est un fait qu'une brique du projet.
    -->|Etape 1|-->|Programme externe|-->|Etape 3|-->|Etape 4|--> ...
    Le probleme c'est qu'on ne sait pas au depart combien de chaines on va traiter.
    Vous me direz c'est pas grave ca marche quand meme. oui c'est vrai, sauf que quand il y a 150 messages, il faut relancer 150 fois l'appli externe, donc 150 secondes en plus, et ce programme doit etre rapide.

    C'est pour ca que je voudrais lancer l'appli externe une bonne fois pour toute sans geler le process.
    En gros, j'aimerais récupérer le résultat des chaines traités sans avoir a faire le .close qui entraine obligatoirement un autre lancement de l'appli.

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 50
    Par défaut
    Pendant que j'y pense, est ce possible de faire tourner cette brique du programme comme daemon?

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 50
    Par défaut
    j'ai tester la blockingqueue
    c'est toujours le même probleme, il faut faire un getOutputStream.close() pour mettre une donnees dans la file d'attente

Discussions similaires

  1. [Administration] "svnadmin: Can't read length line in file"
    Par lennelei dans le forum Subversion
    Réponses: 2
    Dernier message: 07/01/2009, 13h10
  2. Pprobleme de lenteur ImageIO.read
    Par pcouas dans le forum Graphisme
    Réponses: 3
    Dernier message: 11/12/2008, 10h31
  3. boucle while read line
    Par tibal dans le forum Linux
    Réponses: 0
    Dernier message: 25/09/2008, 14h44
  4. read line
    Par Dragon13 dans le forum Shell et commandes GNU
    Réponses: 1
    Dernier message: 01/03/2007, 14h47

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