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

2D Java Discussion :

[JFreeChart] Performance diminuant rapidement


Sujet :

2D Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté Avatar de Torg666
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2008
    Messages
    230
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2008
    Messages : 230
    Par défaut [JFreeChart] Performance diminuant rapidement
    Bonjour,
    Dans le cadre d'une application devant traiter les données d'une carte electronique, je dois afficher les données renvoyées dans un graphe.
    Mon problème est le temps de traitement, dans JFreeChart, d'un createXYLineChart.
    En effet sans le graphe j'ai un temps de traitement de 4/5 milliseconde qui correspond bien au envoie de trame de ma carte qui est d'environ 4/5 ms aussi et j'obtiens des perfommances stable (environ 15000 trames traitées en 1 minute).
    Avec le graphe de JFreeChart, c'est l'hemorragie, sur la premiere minute je suis à environ 9/10 ms pour traiter et afficher un trame, soit le double, et ensuite cela décroit rapidement pour atteindre environ 40ms par trame au bout de 5 minutes...

    Je m'attendais à un perte de performances, mais la c'est beaucoup trop.

    De plus au bout d'un certain temps (environ 2h), j'arrive à consommer toute la mémoire et à planter mon application.

    J'ai essayer, au niveau de l'affichage de retirer les points pour garder un affichage de la derniere minute mais la c'est catastrophique, les performances sont très mauvaise (environ 30ms par trames au bout d'une minute) et en plus j'ai des declenchement d'exception sur les series au niveau des index.


    Je cherche une autre solution pour afficher mes données soit afficher 2 courbes sur 1 graphe, quelqu'un aurai une idée pour afficher un si grand nombre de "point"?

    On va surement me demander le code alors le voilà:
    Déclaration du graphe:
    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
     
    private JFreeChart getJFreeChart() {
    		if(jFreeChart==null){
    			jFreeChart=ChartFactory.createXYLineChart("Résultat", "Temps (sec)", "Volt", gestionnaire.getXYDataset(), PlotOrientation.VERTICAL, true, true, true);
    			XYPlot xyplot = (XYPlot)jFreeChart.getPlot();
    			xyplot.setDomainPannable(true);
    	        xyplot.setRangePannable(true);
    	        xyplot.setDomainZeroBaselineVisible(true);
    	        xyplot.setRangeZeroBaselineVisible(true);
    	        XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer)xyplot.getRenderer();
    	        xylineandshaperenderer.setBaseShapesVisible(false);
    	        xylineandshaperenderer.setBaseShapesFilled(true);
    	        xylineandshaperenderer.setDrawOutlines(true);
    		}
    		return jFreeChart;
    	}
    Déclaration du XYDataset et des series:
    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
     
    	/**
             * Fonction pour créer le XYDataSet
             * @return
             */
    	public XYDataset getXYDataset() {
    		if(xyDataSet==null){
    			XYSeriesCollection collection= new XYSeriesCollection();
    			collection.addSeries(this.getPointSerieCapteur1());
    			collection.addSeries(this.getPointSerieCapteur2());
    			//collection.addSeries(this.getPointSerieSommeVin());
    			xyDataSet=collection;
    		}
    		return xyDataSet;
    	}
    	/**
             * Fonction pour créer la serie de point du capteur1
             * @return
             */
    	public XYSeries getPointSerieCapteur1() {
    		if(pointSerieCapteur1==null){
    			pointSerieCapteur1 = new XYSeries("Capteur1");
    		}
    		return pointSerieCapteur1;
    	}
    	/**
             * Fonction pour créer la serie de point du capteur2
             * @return
             */
    	public XYSeries getPointSerieCapteur2() {
    		if(pointSerieCapteur2==null){
    			pointSerieCapteur2 = new XYSeries("Capteur2");
    		}
    		return pointSerieCapteur2;
    	}
    Déclaration de l'objet de reception, traitement et affichages des données:
    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
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
     
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStreamReader;
     
    import java.util.Calendar;
    import java.util.GregorianCalendar;
    import java.util.TooManyListenersException;
     
    import javax.comm.CommPortIdentifier;
    import javax.comm.NoSuchPortException;
    import javax.comm.PortInUseException;
    import javax.comm.SerialPort;
    import javax.comm.SerialPortEvent;
    import javax.comm.SerialPortEventListener;
    import javax.comm.UnsupportedCommOperationException;
     
    import com.sun.comm.Win32Driver;
     
    public class CommCarteReception implements SerialPortEventListener {
     
    	private ConfigConnexionCarte 	config=null;
    	private Win32Driver 			w32Driver=null;
    	private CommPortIdentifier 		portId=null;
    	private SerialPort 				serialPort=null;
    	private BufferedReader 			fluxLecture=null;
    	private GestPesage 				gestionnaire=null;
    	private BufferedWriter			fluxFichierEcriture=null;
    	private long 					debut=0;
    	private long 					debutSave=0;
    	private double 					tempsCurrent=0;
    	private long 					current=0;
     
    	private String					trame=null;
    	private String					capteur1=null;
    	private String					capteur2=null;
    	private double 					vin1=0.0;
    	private double 					vin2=0.0;
     
    	private Calendar 				dateNow=null;
    	private String 					anFichier=null;
    	private String 					moisFichier=null;
    	private String 					jourFichier=null;
    	private String 					heureFichier=null;
    	private String 					minuteFichier=null;
    	private String 					secondeFichier=null;
     
    	//paramètres de configuration de la carte
    	private String aog1=null;
    	private String fga1=null;
    	private String foa1=null;
    	private String feg1=null;
    	private String coarseOffset1=null;
    	private String aog2=null;
    	private String fga2=null;
    	private String foa2=null;
    	private String feg2=null;
    	private String coarseOffset2=null;
     
    	/**
             * Constructeur
             * @param conf
             * @param gest
             */
    	public CommCarteReception(ConfigConnexionCarte conf,GestPesage gest){
    		config=conf;
    		gestionnaire=gest;
    		aog1=gest.getPga().getaogPGA1();
    		fga1=gest.getPga().getfgaPGA1();
    		foa1=gest.getPga().getfoaPGA1();
    		feg1=gest.getPga().getfegPGA1();
    		coarseOffset1=gest.getPga().getcoarseOffsetPGA1();
    		aog2=gest.getPga().getaogPGA2();
    		fga2=gest.getPga().getfgaPGA2();
    		foa2=gest.getPga().getfoaPGA2();
    		feg2=gest.getPga().getfegPGA2();
    		coarseOffset2=gest.getPga().getcoarseOffsetPGA2();
    		w32Driver = new Win32Driver();
    		w32Driver.initialize();
    		debut=System.currentTimeMillis();
    		debutSave=debut;
    		dateNow=new GregorianCalendar();
    		try {
    			portId = CommPortIdentifier.getPortIdentifier(config.getPortCom());
    			serialPort = (SerialPort) portId.open("FGEPesage", 2000);
    			fluxFichierEcriture=new BufferedWriter(new FileWriter(this.getNow(),true));
    			fluxLecture =new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
    			serialPort.addEventListener(this);
    			serialPort.notifyOnDataAvailable(true);
    			serialPort.setSerialPortParams(config.getBauds(),config.getDataBit(),config.getBitStop(),config.getParite());
    		}catch (NoSuchPortException nspe) {
    			nspe.printStackTrace();
    		}catch (PortInUseException piue) {
    			piue.printStackTrace();
    		}catch (IOException ioe) {
    			ioe.printStackTrace();
    		}catch (TooManyListenersException tmle) {
    			tmle.printStackTrace();
    		}catch (UnsupportedCommOperationException ucoe) {
    			ucoe.printStackTrace();
    		}
    	}
    //LISTENER
    	/**
             * Listener de port com
             */
    	@Override
    	public void serialEvent(SerialPortEvent event) {
     
    		//gestion des événements sur le port :
    		//on ne fait rien sauf quand les données sont disponibles
    		switch (event.getEventType()) {
    			case SerialPortEvent.BI :
    			case SerialPortEvent.OE :
    			case SerialPortEvent.FE :
    			case SerialPortEvent.PE :
    			case SerialPortEvent.CD :
    			case SerialPortEvent.CTS :
    			case SerialPortEvent.DSR :
    			case SerialPortEvent.RI :
    			case SerialPortEvent.OUTPUT_BUFFER_EMPTY :
    				break;
    			case SerialPortEvent.DATA_AVAILABLE :
    				try {
    					//lecture du buffer et affichage
    					trame = (String) fluxLecture.readLine();
    					if(this.checkSum(trame)){
    						capteur1=trame.substring(16, 20);
    						capteur2=trame.substring(21, 25);
    						current=System.currentTimeMillis();
    						tempsCurrent=(current-debut)/1000.0;
    						vin1=this.gestionnaire.getVin(this.signerDecimal(capteur1), aog1, fga1, foa1, feg1, coarseOffset1);
    						vin2=this.gestionnaire.getVin(this.signerDecimal(capteur2), aog2, fga2, foa2, feg2, coarseOffset2);
    						gestionnaire.getPointSerieCapteur1().add(tempsCurrent,vin1);
    						gestionnaire.getPointSerieCapteur2().add(tempsCurrent,vin2);
    						fluxFichierEcriture.write(trame);
    						fluxFichierEcriture.newLine();
    						if((current)-debutSave>=60000){
    							debutSave=current;
    							fluxFichierEcriture.flush();
    							fluxFichierEcriture.close();
    							fluxFichierEcriture=new BufferedWriter(new FileWriter(this.getNow(),true));
    						}
    					}
    				}catch (IOException ioe) {
    					ioe.printStackTrace();
    				}
    			break;
    		}
    	}
    	/**
             * Fonction pour arreter la capture des données de la carte
             */
    	public void stop(){
    		try {
    			fluxFichierEcriture.close();
    		} catch (IOException ioe) {
    			ioe.printStackTrace();
    		}
    		serialPort.close();
     
    	}
    	/**
             * Fonction pour formatter le nom du fichier
             * @param arg
             * @return
             */
    	private String formatZero(String arg){
    		if(arg.length()<2){
    			arg="0"+arg;
    		}
    		return arg;
    	}
    	/**
             * Fonction pour formatter le nom de fichier de svg 
             * @return
             */
    	private String getNow(){
    		String now=null;
     
    		dateNow=dateNow.getInstance();
    		anFichier=dateNow.get(Calendar.YEAR)+"";
    		moisFichier=this.formatZero((dateNow.get(Calendar.MONTH)+1)+"");
    		jourFichier=this.formatZero(dateNow.get(Calendar.DAY_OF_MONTH)+"");
    		heureFichier=this.formatZero(dateNow.get(Calendar.HOUR_OF_DAY)+"");
    		minuteFichier=this.formatZero(dateNow.get(Calendar.MINUTE)+"");
    		secondeFichier=this.formatZero(dateNow.get(Calendar.SECOND)+"");
    		now=anFichier+"-"+moisFichier+"-"+jourFichier+"-"+heureFichier+"-"+minuteFichier+"-"+secondeFichier+".svg";
    		return now;
    	}
    	/**
             * Converti la sortie des capteurs d'un decimal à un decimal signé
             * @param arg
             * @return
             */
    	public short signerDecimal(String arg){
    		return (short)Integer.parseInt(arg,16);
    	}
    	/**
             * Test le checkSum
             * @param arg
             * @return
             */
    	private boolean checkSum(String arg){
    		int 	sumDonne=0;
    		int 	sum=0;
    		String 	ligneChar=null;
    		if(arg!=null){
    			if(arg.length()==33){
    				sumDonne=Integer.parseInt(arg.substring(26, 31));
    				ligneChar=arg.substring(0, 26);
    				for(int cpt=0;cpt<ligneChar.length();cpt++){
    					sum=sum+ligneChar.charAt(cpt);
    				}
    				sum=65535-sum;
    				if(sumDonne==sum){
    					return true;
    				}
    			}
    		}
    		return false;
    	}
    }
    Exemple:
    Je fais 1 nouveau fichier de sauvegarde toute les minutes.
    En "commentant" les 2 lignes qui ajoutent les "points" sur le graph, mes fichiers de sauvegarde font environ 520Ko.
    En les laissant, le premier fichier fais environ 267Ko, le second 123Ko..., jusqu'à se "stabiliser" à environ 50Ko.

    Merci d'avance

  2. #2
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Ve qque je te conseille très vivement c'est de passer ton appli sous un profiler comme VisualVM qui te permettra de voir ou les pertes de mémoire et temps processeur sont réalisées. (mieux vaut utiliser java6 pour utiliser correctement ce profiler)

  3. #3
    Membre expérimenté Avatar de Torg666
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2008
    Messages
    230
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2008
    Messages : 230
    Par défaut
    Bonjour,
    Le problème n'est pas de localiser où est la perte de perfomance, c'est déjà fait, mais plutôt d'y remedier.
    J'ai fais des modifications sur mon developpement en déleguant le dessin des courbes dans un thread. La "sauvegarde" de mes trames de données est aussi bonne par contre le dessin des courbes est toujours aussi lent et "instable".
    Je dois trouver un autre "objet" me permettant de tracer 2 courbes soit environ 30k pts par minute...



    merci d'avance

  4. #4
    Invité de passage
    Inscrit en
    Avril 2008
    Messages
    1
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 1
    Par défaut
    salut,

    JFreeCharts n'est pas prévu pour du real-time et les perfromances se dégradent rapidement si la taille du dataset est importante. Une solution
    consiste à « filtrer » les données injectées dans le dataset: un dataset de 100'000 éléments sera affiché avec un plot de 3'000 voir 4'000 points (le nombre de points dépend de la taille de l'écran / pixels). Cela signifie que plusieurs données seront affiché par un seul point (pixel). La stratégie consiste justement à limiter le volume d'information du dataset à l'essentiel. Attention, car si tu utilise des zoom dans ton jfreecharts, il faudra en tenir compte et modifier les valeurs dans le dataset filtré.

    Un autre solution consiste à se tourner vers d'autres lib tels que QN Plot, LiveGraph et JChart2D qui sont prévues pour du real-time.

    ciao
    luca

  5. #5
    Membre expérimenté Avatar de Torg666
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2008
    Messages
    230
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2008
    Messages : 230
    Par défaut
    Merci, je vais essayer les autres lib

Discussions similaires

  1. [JFreeChart] Performance d'affichage
    Par niikkko dans le forum Composants
    Réponses: 1
    Dernier message: 24/09/2012, 11h43
  2. Performance - Recherche dans une arborescence rapidement.
    Par BobbyWeb dans le forum Zend Framework
    Réponses: 3
    Dernier message: 07/04/2011, 15h56
  3. [AJAX] performances fortement diminuées avec un Update panel (et IE)?
    Par cortex024 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 28/06/2007, 12h40

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