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 :

[optimisation] problème de perf sur une boucle rs.next()


Sujet :

Langage Java

  1. #1
    Nouveau Candidat au Club
    Inscrit en
    Juin 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 7
    Points : 1
    Points
    1
    Par défaut [optimisation] problème de perf sur une boucle rs.next()
    Bonjour,

    J'ai un gros problème de perf en essayant de lire beaucoup de lignes (200000) en base.
    Le problème n'est pas dans la requête SQL, mais bien quand je remplie une ArrayList avec mon résultat.

    Le code concerné :

    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
    -------
    ArrayList itemLst;
    ArrayList itemLstLst;
     
    // Lecture des informations
    while(rs.next())
    {
    itemLst = new ArrayList();
     
    itemLst.add(rs.getString("field1"));
    itemLst.add(rs.getString("field2"));
    /* ...*/
    itemLst.add(rs.getString("field30"));
     
    itemLstLst.add(itemLst);
    }
    ------
    Est-ce que quelqu'un sait comment optimiser ce code ?
    Le traitement des données dans les listes après est lui performant et beaucoup plus rapide, bizarre...

  2. #2
    in
    in est déconnecté
    Membre expérimenté Avatar de in
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 612
    Points : 1 718
    Points
    1 718
    Par défaut
    pense à la balise code ...

    je ne sais pas trop mais peut etre qu'initialisé la taille de ton arrayList à 200000 permettrait d'améliorer un peu les choses ....
    "If email had been around before the telephone was invented, people would have said, 'Hey, forget email! With this new telephone invention I can actually talk to people!"

    Besoin d'une nouvelle méthode pour développer ? -> http://www.la-rache.com/

  3. #3
    Nouveau Candidat au Club
    Inscrit en
    Juin 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par in
    pense à la balise code ...
    Merci de l'avoir fait pour moi, je débute sur ce forum

    Citation Envoyé par in
    je ne sais pas trop mais peut etre qu'initialisé la taille de ton arrayList à 200000 permettrait d'améliorer un peu les choses ....
    Le problème est que je n'ai aucune idée du nombre de ligne que je vais récupérer...
    Et je ne crois pas (j'ai pas vu comment) récupérer le nombre de ligne rendue dans le ResultSet.

  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
    Salut,


    Ton problème de performances (de quel ordre de temps s'agit-il ?) vient surement du fait que tu alloues beaucoup de mémoire :
    • 200 000 ArrayList
    • 6 000 000 de String
    As-tu vraiment besoin de tout stocker avant d'effectuer tes traitements ? Tu obtiendrais surement de meilleurs résultats si tu effectueais tes traitements lignes par lignes...


    Si ce n'est pas possibles, quelques pistes :
    • Comme cela a été dit, tu peux initialiser tes ArrayList en spécifiant leurs tailles puisque. Cela t'éviteras que la taille du tableau soit réalloué (et donc une copie de tableau), mais également un gain de mémoire. Pour ton tableau global (itemLstLst) tu peux utiliser la solution de la FAQ : Comment connaître le nombre de lignes/colonnes d'un ResultSet ?
      Et tu peux faire la même chose pour tes ArrayList temporaire (itemLst) puisque la taille semble fixe (30)
    • Si les valeurs qui te sont retourné par la BD sont souvent les mêmes, tu peux utiliser la méthode intern() de String pour éviter les doublons...
    a++

  5. #5
    Nouveau Candidat au Club
    Inscrit en
    Juin 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Merci pour les pistes, je regarde ça et je vous tiens au courant !

  6. #6
    in
    in est déconnecté
    Membre expérimenté Avatar de in
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 612
    Points : 1 718
    Points
    1 718
    Par défaut
    Citation Envoyé par jaaaaf
    Merci de l'avoir fait pour moi, je débute sur ce forum
    c'est pas moi, c'est wichtounet
    "If email had been around before the telephone was invented, people would have said, 'Hey, forget email! With this new telephone invention I can actually talk to people!"

    Besoin d'une nouvelle méthode pour développer ? -> http://www.la-rache.com/

  7. #7
    Nouveau Candidat au Club
    Inscrit en
    Juin 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    J'ai fais des tests avec vos conseils, hélas pas trop de résultat
    Le positionnement de ma liste à 30, et de ma liste de liste (positionné en dur) ne chage rien aux perfs.
    En + je ne peux avoir le nombre de lignes puisque mon ResultSet est en TYPE_FORWARD_ONLY

    Seul le String.intern() semble améliorer les perfs de 10%. C'est déjà ça, mais je suis encore loin de ce que je voudrai obtenir...

    Je réponds aux questions de adiGuba.
    Citation Envoyé par adiGuba

    Ton problème de performances (de quel ordre de temps s'agit-il ?)
    Ca reste relatif à la puissance du PC utilisé, mais en relatif ça donne ça :
    • Temps de traitement de la requête (sur un serveur BD) 12s
    • Temps de traitement de ma boucle 30s
    • Temps de traitement et de création de tous les objet à partir de ma liste de liste : 3s! Le plus ettonnant est que dans ces créations d'objets, il est créé de nouveau plein de listes et pourtant ce n'est pas long !
    Citation Envoyé par adiGuba
    As-tu vraiment besoin de tout stocker avant d'effectuer tes traitements ? Tu obtiendrais surement de meilleurs résultats si tu effectueais tes traitements lignes par lignes...
    Oui c'est sur.
    Ca doit être possible de traiter ligne par ligne, mais il faut revoir tout le code derrière, et ça je voulais éviter parceque c'est un travail énorme !

    Bref, si vous avez d'autres idées...

  8. #8
    Membre éclairé Avatar de g_rare
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 608
    Points : 683
    Points
    683
    Par défaut
    Citation Envoyé par jaaaaf
    • Temps de traitement de la requête (sur un serveur BD) 12s
    Pour moi le problème vient de la structure de ta requête : il est "irréaliste" de ramener 200.000 lignes de B.D. et d'en faire des calculs, sachant que des méthodes SQL comme <<count>> ou <<sum>> et des techniques de tri/filtrage comme <<order by>> ou <<where>> sont là pour ça !

    Citation Envoyé par jaaaaf
    • Temps de traitement de ma boucle 30s
    PS_ ça fait quand-même plus de 6000 lignes de ResultSet traitées par seconde ; c'est pas mal...

    " Jag blev dömd för fildelning och allt jag fick var en sketen t-shirt. " (tankafritt.nu)
    PAS DE REPONSE PAR MESSAGE PRIVE ! Penser au bouton Résolu en bas de la discussion...

  9. #9
    Nouveau Candidat au Club
    Inscrit en
    Juin 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    En fait, je viens de découvrir que le ResultSet ne récupère pas toutes les données en base et du coup c'est surtout le rs.next() qui est long car il récupère encore des données en base !
    Le code suivant met 16s (sur mon PC) à s'exécuter, donc l'essentiel du temps passé dans ma boucle est pris par le rs.next()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    while(rs.next())
    {
    itemLst = null;
    }
    Je vais investiguer sur le fetch du ResultSet.

  10. #10
    Nouveau Candidat au Club
    Inscrit en
    Juin 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par g_rare
    Pour moi le problème vient de la structure de ta requête : il est "irréaliste" de ramener 200.000 lignes de B.D. et d'en faire des calculs, sachant que des méthodes SQL comme <<count>> ou <<sum>> et des techniques de tri/filtrage comme <<order by>> ou <<where>> sont là pour ça !
    Je suis tout a fait d'accord, mais je n'ai hélas pas vraiment le choix, c'est le client qui veut ça
    Ma requête ne rapporte que les données utiles, elle fait déjà pas mal de lignes avec de belles parties where et order by...

  11. #11
    in
    in est déconnecté
    Membre expérimenté Avatar de in
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 612
    Points : 1 718
    Points
    1 718
    Par défaut
    daccord avec g_rare, il faut utiliser le plus possible les capacité de traitement de la BD. Elle est faite pour ça.

    Sinon pour ton nombre de lignes, tu peux passer ton resultSet à scrollable non ?

    pour la tailkle du fetch, ce que tu gagneras en temps de traitement, tu le perdra en mémoire je pense.

    enfin, j'insiste mais tu devrais étudier le coté amont de l'histoire et passer par des vues ou des proc stockées (ou autre bien entendu).

    [EDIT] OK, je retire vous ton précédent post, que nous avons écrit en meme temps ...
    "If email had been around before the telephone was invented, people would have said, 'Hey, forget email! With this new telephone invention I can actually talk to people!"

    Besoin d'une nouvelle méthode pour développer ? -> http://www.la-rache.com/

  12. #12
    Nouveau Candidat au Club
    Inscrit en
    Juin 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Comme écrit dans : http://java.developpez.com/faq/jdbc/...esultset#fetch, j'ai positionné un fetch à 1000, et c'est beaucoup mieux !

    C'est plus consomateur de mémoire, mais bien plus perf. La boucle (vide) passe de 16s à 4s.

    Je suis pas encore au résultat espéré (au total), mais je progresse !

Discussions similaires

  1. [XL-2007] Problème macro excel 2007 sur une boucle
    Par neo222816 dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 18/08/2014, 13h34
  2. problème de perfs sur une base 10g
    Par cyclone_yas dans le forum Administration
    Réponses: 3
    Dernier message: 21/09/2011, 19h50
  3. ASP petit problème à propos sur une boucle if
    Par nicodu59 dans le forum ASP
    Réponses: 2
    Dernier message: 02/08/2007, 11h21
  4. [MySQL] problème sur une boucle for
    Par leclone dans le forum PHP & Base de données
    Réponses: 13
    Dernier message: 28/12/2006, 11h33
  5. Problème sur une boucle
    Par Mateache dans le forum ASP
    Réponses: 6
    Dernier message: 31/01/2006, 10h48

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