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 :

Analyse complexité algo: Programme qui met beaucoup de temps


Sujet :

Langage Java

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 14
    Points : 7
    Points
    7
    Par défaut Analyse complexité algo: Programme qui met beaucoup de temps
    Bonjour à tous,

    Je viens ici pour demander un petit coup de main concernant un de mes programmes qui mets beaucoup de temps à s'exécuter.
    Meme si le nombre de donnée est relativement tres élévé, je pense que mon algorithme y est aussi pour un peu.
    L'idée du programme est celle ci:
    Pour une sous-famille d'un article, conter les qté des articles vendus et faire leur total.
    Les données dont j'ai à disposition
    un tableau t1 avec chaque article vendu ainsi que le prix et la qté.
    un tableau t2 avec les sous familles (sans doublons)
    un tableau t3 avec les familles associées à leur sous famille ainsi que les articles y faisant partie (ici avec doublons sur les familles et sous famille).

    N'ayant pas trouvé un moyen de retour un triplet (sous fam, qte, prix)
    du coup j'ai fait deux hashmap un avec <Sous famille, qté> et un avec <Sous famille , total>


    correspondance des variables:
    resultatCaisse = t1

    Je vous demande de m'excuser par avance pour la longueur du code que je mets.

    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
     
    try {
    if(resultatCaisse !=null){
    	while (resultatCaisse.next()){
    					hm3.put(resultatCaisse.getString(1),true);
    				//System.out.println(resultatCaisse.getString(1));		
    				}
    			}else{
    				hm3.put("pas de ventes"	,true);
    			}
    			//resultatCaisse.beforeFirst();
     
    		//Ajout des sous familles existantes
     
    			while(resultatSfamilleDistinct.next()){
    				vecteurSousFamDis.addElement(resultatSfamilleDistinct.getString(1));
    			}
    			resultatSfamilleDistinct.beforeFirst();
    		}catch (SQLException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
     
    	try{
    		if(resultatCaisse!=null){
    			resultatCaisse.beforeFirst();
    		//Parcours du tableau des sous familles
    		while(resultatSfamilleDistinct.next()){
    			//recupere le code sf courant
    			String codesf=resultatSfamilleDistinct.getString(1);			
    			hm1.put(codesf, 0.0);
    			hm2.put(codesf, 0);
    			//parcours lignes caisse
    			while(resultatCaisse.next()){
    				//parcours les sous familles choisies
    				String codeart=resultatCaisse.getString(1);
    				//tableau permet de savoir si l'article a ete trouvé auparavant dans le resultat resultatSfamAvecFamChoisie
    				//ce qui evite de reparcourir  chaque occurrence de ce code article le resultatSfamAvecFamChoisie
    				//faux pour dire que l'article n'est pas encore trouve
    				boolean flag=false;
    				if(hm3.get(codeart)){
    					while(resultatSfamAvecFamChoisie.next()){
    						//si l'article caisse egal article dans sous famille choisie
    						String sfc=resultatSfamAvecFamChoisie.getString(2);
    						//Si le code article est plus grand ou egal au premier code article de resultatSfamAvecFamChoisie
    						//alors les autres tests peuvent être fait. sinon c'est que l'article ne fait pas partie du resultat, donc inutile de le tester sur tout resultatSfamAvecFamChoisie
    					 if(Integer.parseInt(codeart)>=Integer.parseInt(sfc)){
    							//teste si le code article est present dans resultatSfamAvecFamChoisie
    						if(codeart.compareTo(sfc)==0){
    							//si cette sous famille choisie egal sous famille courante 
    							if(resultatSfamAvecFamChoisie.getString(1).compareTo(codesf)==0){
    								//System.out.println(codesf + "::"+ codeart + ":"+hm1.get(codesf)+":"+resultatCaisse.getDouble(3));
    								hm1.put(codesf,(hm1.get(codesf)+resultatCaisse.getDouble(3)));	
    								hm2.put(codesf,(hm2.get(codesf)+resultatCaisse.getInt(2)));
    								flag=true;
    								break;
    							}
    						flag=true;
    						}
    					 }else{
    						 break;
    					 }
    					}
    					//si le flag placé dans le test de code art et resultatSfamAvecFamChoisie est vrai c'est que l'article à ete trouvé une fois
    					//sinon l'article n'est pas trouvé lorsqu'on de parcourir tout resultatSfamAvecFamChoisie a fini donc on met dans le tableau hm3 flag à faux afin de ne plus le chercher dans les recherches futures.
    					if(!flag)hm3.put(codeart, false);
    				}
    				resultatSfamAvecFamChoisie.beforeFirst();
    			}
    			resultatCaisse.beforeFirst();
     
    	}
    			}else{
    				hm1.put("pas de vente", 0.0);
    				hm2.put("pas de vente", 0);
    			}
    	}catch(SQLException e){
    		e.printStackTrace();
    	}
    		tabHash[0]=hm1;
    		tabHash[1]=hm2;

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    suite(...)
    resultatSfamilleDistinct= t2
    resultatSfamAvecFamChoisie=t3

    La taille des donnée de t3 varie entre 9000 et 10000
    taille de t2 = 10;
    taille de t1 varie met dans les 5000 lignes.

    Le code fonctionne, c'est juste qu'il met beaucoup de temps (4h voire plus)

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2007
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 33
    Points : 35
    Points
    35
    Par défaut
    Si tu veut accélérer ton traitement, il y a 2 solutions que je te propose :
    - trouver une astuce algorithmique pour ne pas avoir besoin de faire une de tes 3 boucles pour passer la complexité de n puissance 3 a n², tu gagnera déjà énormément de temps.
    - diminuer le volume de tes données : est-ce ce que tu ne pourrais pas faire un tri des données en sql pour ne pas avoir à parcourir complétement T1 et T3?


    En règle générale quand il y a des quantité importante de données a sélectionner, il vaut mieux faire le maximum d'opération avec sql et non avec ton programme!

  4. #4
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Points : 7 163
    Points
    7 163
    Par défaut
    Ton problème algorithmique majeur est que les données sont en vrac.
    Il faut commencer par les trier.
    Si j'ai bien compris la problématique, voici ce que je te propose :
    1. t1 doit être un tableau ordonné selon l'identifiant de l'article (un numéro serait idéal)
    2. trier t3 selon l'identifiant des articles
    3. parcourir séquentiellement t1 et t3 (comme si on les mettaient côte à côte) et construire t4 contenant la famille, la sous-famille et l'article, ainsi que le prix et la quantité de l'article (en fait un merge des infos entre t1 et t3)
    4. trier t2 selon l'identifiant de la sous-famille
    5. trier t4 selon l'identifiant de la sous-famille
    6. parcourir séquentiellement t2 et t4 (comme si on les mettait côte à côte) sur l'identifiant de la sous-famille et ajouter les quantités et prix des articles tant que la sous-famille lue ne change pas.

    Puisque tes tableaux ne contiennent que quelques milliers d'éléments, ce sera très rapide.

    bien sûr, au lieu de construire t4, tu peux construire directement t3 avec les infos complémentaires pas encore spécifiées.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    Merci beaucoup pour vos réponses!!,

    Déjà cela me met sur une tres bonne piste.

    Je reviens vous en dire polus des que j'ai fait des modifs.

  6. #6
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Je vois que tu fais plusieurs requetes SQL pour faire ton calcul, et que tu fais, a priori, transiter beaucoup de données et que tu joue à faire revenir en arrière tes resultset. Le transfert, ça prend du temps, le stockage ça prend de la mémoire. Le SQL c'est une language. Il est de loin préférable que crée directement une requête SQL qui te donne ton résultat final. Vu le style de calcul,c'est normalement réalisable sans soucis par une SGBD en des temps très faible si tes indexations sont correctes.

    Donne nous tes tables, ce que tu veux calculer et on pourra t'aider.

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    Bonjour à tous et désolée de données des nouvelles si tardivement,

    Merci de vos réponses,
    Pour répondre à Tchize, j'utilise plusieurs resultSet car je ne travaille pas sur le meme sgbd, il y en a un qui est sous SqlServer, et l'autre c'est de l'as400.

    Finalement, apres m'etre renseignée un plus, les données que je recuperais sur SqlServer ,il y a une bibliotheque dans l'as400 où je pouvais les trouver.

    Ce qui m'a carrement facilité la tache car je n'ai plus qu'une requete sql.


    Merci encore.

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

Discussions similaires

  1. Programme qui consomme beaucoup de CPU
    Par houssine91 dans le forum Général Java
    Réponses: 4
    Dernier message: 16/03/2013, 15h18
  2. Analyse d'un programme qui se "fige"
    Par magellan94 dans le forum C#
    Réponses: 10
    Dernier message: 12/12/2011, 11h59
  3. Réponses: 4
    Dernier message: 14/11/2011, 21h04
  4. optimiser une reqête qui mets beaucoup de temps
    Par rickways dans le forum Requêtes
    Réponses: 6
    Dernier message: 10/09/2009, 20h10
  5. programme qui consomme beaucoup de memoire
    Par gaut dans le forum Windows
    Réponses: 10
    Dernier message: 01/02/2005, 20h33

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