Partage
  • Partager sur Facebook
  • Partager sur Twitter

Probléme de fluidité avec file...

LinkedList

    18 juin 2009 à 16:23:40

    Salut,

    je suis en train de prorammer un petit "Jeu de la vie". (Le jeu de la vie)
    J'ai terminé le coeur du programme et j'essaie d'ajouter quelques fonctionnalités ...
    La fonctionnalité qui pose probléme :

    Effectuer et sauvegarder des évolutions à l'avance pour pouvoir ensuite donner des informations sur l'"avenir". Par exemple savoir dans combien de cycles une cellule particulière va mourir etc ...

    Pour obtenir ce résultat j'ai décidé d'utiliser le temps entre 2 évolutions pour stocker un maximum d'états dans une file.

    Donc le programme fonctionnera comme ça :

    -simuler et stocker un maximum d'états dans la file durant le délai.
    -afficher le 1er état stocké de la file.
    -simuler et stocker un maximum d'états dans la file durant le délai.
    -afficher le 2éme état stocké dans le file.
    ...etc jusqu'à l'interruption du programme(je donnerai une limite d'états stockés plus tard).

    Voila une partie de mon code commenté :
    /* file est une LinkedList de tableau
              * evolution.getNext().getTableau() retourne le tableau de l'évolution
              * suivante
              * */
             while(true){
                  début = System.currentTimeMillis();                   //Temps actuel en milliseconde.
                  do{
                      file.add(Plateau.copie(evolution.getNext().getTableau()));       //On place des copies (pour que chaque tableau aie une référence différente) d'évolutions successives sous forme de tableau dans la file
                  }while((System.currentTimeMillis() - début) < délai); //temps que le délai n'est pas écoulé.
                  pan.setTableau(file.poll());                          //après ce délai , donne le premier tableau stocké au Panneau (extend JPane). 
                  pan.repaint();                                        //on actualise le panneau (extend JPane)
              }
    
         }
    

    Le problème viens de la fluidité du programme ... à partir de 100 évolutions stockés il y a déjà des ralentissements (avec un délai de 100 ms environ) et à partir de 300 le délai n'est plus suffisent et le temps d'un seul ajout dépasse le délai.
    Le plateau utilisé pour les tests fait 120*120 cellules.
    Il n'y avait aucune latence avant d'ajouter la file.
    Je précise que chaque cellule est instanciée car j'ai l'intention de leur donner des informations personnalisées (couleur , temps avant mort etc...).
    Est-ce ça qui fait tant ramé ? Dans ce cas je ne vois qu'une seule possibilité : "généraliser" le tableau avant de le sauver... mais j'aimerai avoir avoir votre avis avant de modifier le code...

    merci d'avance.
    • Partager sur Facebook
    • Partager sur Twitter
      18 juin 2009 à 18:38:31

      Quand on utilise les collections, j'ai lu qu'il fallait optimiser au maximum l'utilisation de la mémoire quand elles deviennent assez grandes... Ca semble évident mais bon.
      Ca commence déjà par utiliser des byte par exemple au lieu des int si possible.

      Ensuite comme je vois un repaint(), ça peut poser problème d'utiliser le passive rendering si la mise à jour graphique est trop fréquente. Parce que repaint() ne s'occupe pas de repeindre comme son nom l'indique mais de poster une série d'instructions dans le Thread utilisé par Swing (Event Dispatch Thread).

      Je vois une boucle infinie, j'espère qu'elle est dans un Thread à part.

      Et je te conseille de lire des choses sur la gestion de la concurrence en Swing, qui est une chose vraiment pas simple à aborder...
      • Partager sur Facebook
      • Partager sur Twitter
        18 juin 2009 à 23:01:17

        Je vais essayer d'optimiser tout ça en utilisant des primitifs moins gourmand.
        Je début aussi en mode graphique (j'avoue j'ai un peu de mal ).
        Sinon la boucle infinie c'est juste pour tester le programme.

        Voila la méthode principale de Panneau :
        public void paintComponent(Graphics g){
                g.setColor(Color.white);
                g.fillRect(0, 0, this.getWidth(),this.getHeight());
                g.setColor(Color.black);
        
                for(int i=0,x=0;i<Plateau.TAILLE;i++,x+=5){
                    for(int j=0,y=0;j<Plateau.TAILLE;j++,y+=5){
                        if(tableau[i][j].getEtat()){
                            g.fillRect(x,y,5,5);
                        }else{
                            g.drawRect(x,y,5,5);
        
                        }
                    }
                }
            }
        

        En gros c'est un tableau Cellule.
        La méthode getEtat() de Cellule retourne true ou false en fonction de l'état de la cellule (vivante ou morte).

        Je fais simplement ou boucle qui dessine des petits carrés vides ou pleins de 5 pixels de coté en fonction de l'état.
        Je pense pas que ce soir la solution la plus optimisée mais ça donne un assez bon résultat.



        • Partager sur Facebook
        • Partager sur Twitter
          18 juin 2009 à 23:21:22

          Nan mais oui d'accord c'est bon pour la méthode.
          De toute manière si ton programme fonctionne, c'est bon signe !

          Mais pour l'optimisation, je te conseille de jeter un œil du côté de l'active rendering.
          Au lieu d'appeler des repaint() qui ne peignent pas toujours, tu vas créer une méthode qui dessine sur une BufferedImage ou VolatileImage, puis faire un drawImage de cette dernière dans une méthode paintScreen() de ta composition.
          A ce moment là tu as un contrôle total sur le processus de peinture à l'écran, ce qui permet de l'optimiser à souhait.

          Ma foi on utilise beaucoup cette méthode pour les jeux ; aussi j'ai peine à croire que ce soit ce qui manque à ton programme.
          Utilises-tu des Thread à un moment ? Quelle est la consommation de CPU durant l'exécution de ton programme ?
          • Partager sur Facebook
          • Partager sur Twitter
            18 juin 2009 à 23:38:45

            Je code avec vi sous un Ubuntu dans Virtual Box donc je doute que l'activité du processeur soit très objective.
            Sinon c'est quoi un Thread ? des processus séparés ? Le seul chôse que je connaisse en rapport avec Thread c'est Thread.sleep(int) :p .
            Mais peut être que le problème vienne du fait que je manipule beaucoup la liste et qu'a chaque modification toutes les entrés doivent être décalée dans un tableau (les adresses en mémoire quoi ).Et je crois que 120*120*300 ça commence à faire pas mal de mouvement .

            Je vais essayer de limiter ça en n'utilisant que 2 objets Cellule , une morte et une vivante , on verra bien :) (2*300 ça sera déjà plus raisonnable).


            Edit : Bon je viens de monter à 1300 avant de ramer :magicien:
            C'est suffisent mais il y a surement un problème ailleurs parce que c'est un peu ridicule à l'échelle de la machine ... Par contre ce n'est pas transparent vu que à chaque fois il y a des saccades (le temps d'un tour de boucle et le délai est dépassé).
            Peut-être que je pourrai m'en sortir avec des thread (si j'ai bien compris ce que c'est ...).
            • Partager sur Facebook
            • Partager sur Twitter

            Probléme de fluidité avec file...

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown