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 vecteur de classe complexe


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 84
    Par défaut Optimisation vecteur de classe complexe
    Bonjour,

    J'aimerai optimiser l'exécution du traitement sur des vecteurs et matrices de complexes. La taille des vecteurs et matrices peut être très conséquente.

    J'ai ainsi trois questions sur l'implémentation de ma class "MyComplex":

    1) dois je utiliser un tableau de taille 2 ou plus classiquement deux doubles ?
    l'idée c'est qu'avec le tableau on est sur que les deux doubles sont stockées de façon contigu en mémoire. on devrait avec le tableau gagner en temps d'accès. non?
    soit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public class MyComplex {
    	private double real;
    	private double imag;
    ...
    }
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public class MyComplex {
    	private double[] data;
     
    	public double getReal(){
    		return data[0];
    	}
     
    	public double getImag(){
    		return data[1];
    	}
    ...
    }
    2) Concernant ma class vector. Dans 98% du temps je connais la taille de ma matrice ou vecteur que j'utilise. Or pour me simplifier la vie j'ai utilisé dans ma class vector un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    protected ArrayList<MyComplex> vect;
    Serait il plus optimisé en terme de temps d'accès et de traitement d'avoir un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    protected MyComplex[] vect;
    ?

    de même que précédemment l'idée c'est qu'avec le tableau on est sur que les doubles sont stockées de façon contigu en mémoire. De plus le ArrayList peut attribuer plus de donnée que demandée. D'où une augmentation de la mémoire utilisée.

    3) plus technique je pense, dans ma class "MyComplex" j'ai les méthodes mathématique pour manipuler les complexes (add, sub,..., sin, cos...). serait il plus optimisé d'avoir une class générique comme "java.lang.Math". qui possède tout ses méthodes en static pour manipuler les complexes?

    J'ai entendu dire que le fait d'associer beaucoup de méthode à une class pouvait faire augmenter la représentation de cette class en mémoire. Or je peux avoir de très grosse matrices en mémoire et dans certain cas je sature ma mémoire (java en 32Bits sur machine en 64bits). Avant de passer en 64bits j'aimerai, en premier lieu, optimiser mon code.

    merci d'avance pour tous vos commentaires.

    Cordialement,
    Sébastien.

  2. #2
    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 <_oodTi96Tiboo_> Voir le message
    1) dois je utiliser un tableau de taille 2 ou plus classiquement deux doubles ?
    l'idée c'est qu'avec le tableau on est sur que les deux doubles sont stockées de façon contigu en mémoire. on devrait avec le tableau gagner en temps d'accès. non?
    Perso je doute fortement que cela ait un impact...
    Du coup je resterais sur la version avec deux doubles (plus lisible et plus pratique).


    Citation Envoyé par <_oodTi96Tiboo_> Voir le message
    2) Concernant ma class vector. Dans 98% du temps je connais la taille de ma matrice ou vecteur que j'utilise.
    Si tu connais la taille, tu peux l'indiquer au constructeur d'ArrayList, cela permettra d'éviter quelques redimensionnement.

    Sinon encore une fois la différence doit être minime. ArrayList utilisant déjà un tableau en interne...


    Citation Envoyé par <_oodTi96Tiboo_> Voir le message
    3) plus technique je pense, dans ma class "MyComplex" j'ai les méthodes mathématique pour manipuler les complexes (add, sub,..., sin, cos...). serait il plus optimisé d'avoir une class générique comme "java.lang.Math". qui possède tout ses méthodes en static pour manipuler les complexes?

    J'ai entendu dire que le fait d'associer beaucoup de méthode à une class pouvait faire augmenter la représentation de cette class en mémoire. Or je peux avoir de très grosse matrices en mémoire et dans certain cas je sature ma mémoire (java en 32Bits sur machine en 64bits). Avant de passer en 64bits j'aimerai en premier optimiser mon code.
    Non : le nombre de méthode n'influe pas sur la quantité de mémoire utilisées par les instances, donc cela ne changera rien non plus.



    Citation Envoyé par <_oodTi96Tiboo_> Voir le message
    Avant de passer en 64bits j'aimerai en premier optimiser mon code.
    C'est à dire ? Quels sont les problèmes que tu rencontres exactement ?
    Avant de "pourrir" ton code il serait préférable de cibler l'origine de ces problèmes !


    a++

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 84
    Par défaut
    Bonjour AdiGuba,

    Tes réponses me plaisent dans un sens, car elles ne me font pas modifier mon code .
    Toutefois cela ne me donne pas de piste d'optimisation .

    Pour expliquer mon besoin, j'ai à traiter un grand nombre de fichier. Actuellement j'ai plus de 1500 fichiers (mais je ne les traiterai que séquentiellement ou par paire faute de mieux). Dans chaque fichier (xml) j'ai quelque info à stocker puis il pointe sur un autre qui contient les données. Pour faire simple c'est une matrice de point, genre 100x100. Pour chaque point j'ai une liste de valeur en complexe, genre 1600 valeurs.
    Ce qui fait dans cet exemple
    2 doubles x 1600 x 100x100 + (data info c'est pas lourd) soit environs 130Mo de donnée par fichier.
    Actuellement JVM = 400Mo + 400Mo par fichier ouvert. Soit si j'en ouvre 2 cela plante.

    C'est cette taille que je cherche à réduire au max car j'ai plusieurs fichiers à ouvrir + la taille de la machine virtuel sera arrive rapidement à 1.2Go là ou le PC 32bits plante (limitation mémoire Windows pour un process sur 32bits d'après ce que j'ai lu.).
    Après calcul rapide j'ai 130Mo de donnée toutefois je note une augmentation du processus de 400Mo après le chargement d'un fichier.

    De plus je chercher également à optimiser le temps d'accès aux données car je dois réaliser des traitements lourds sur les matrices (plusieurs FFT2D).
    Si vous avez de l'info sur comment optimiser l'accès aux données en JAVA je suis preneur.

    Sébastien.

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Je crois que tu calcul mal tes tailles :/


    Tu stocke tes complex dans une class Complexe. Ca fait donc

    2 doubles: 128bits
    1 référence de l'instance vers Complex.class: 32 bits

    minimum syndical: 160 bits.

    1600*100*100*160bits, chez moi ça fait déjà 300M, et ça c'est le minimum.
    Rajoute à ça que l'ArrayList grandis par à coups, et donc peut avoir une taille disons environ 1/3 trop grande, on arrive à 400M. En rejoutant tes structure intermédiaire, on devrais arriver aux 400M.

    L'augmentation du nombre de méthode augmente l'empreinte de la classe, oui, mais pas l'empreinte des instance, donc ce n'est pas à multiplier par la taille de la matrice.

    Si tu as beaucoup de données à faire tenir en mémoire, il n'y a pas d'avance, ce qui a le moins d'overhead / donnée, c'est le tableau. Donc tu devrais avoir un truc genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public class ComplexEntry {
     
        double[] real = new double[1600];
        double[] complex = new double[1600];
    }
    Faire ensuite une arrayList d'arraylist de ça devrais déjà consommer un peu moins:

    (1600*128+2*32+32)/1600 ~= 128.06bits / entrée, ce qui est presque la taille de la donnée brute que tu veux gérer.

    Difficile d'aller beaucoup plus bas. Sauf à utiliser des floats au lieu de doubles.

    Après, faudra voir tes algos pour qu'ils puissent travailler une page à la fois. Ou alors passer à un jvm 64bits et une grosse mémoire

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 84
    Par défaut
    Bonjour Tchize_,

    Effectivement j'ai inversé le float(4 octects) et le double(8 octects) autant pour moi .

    Concernant la référence à ajouter, y a t'il un autre moyen que de passer par l'utilisation de deux tableaux de double?

    Le must pour moi serait une option magic donnée au compilation pour qu'il me transforme cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public class MyComplex {
    	private double real;
    	private double imag;
    ...
    }
     
    {
    ...
     
    MyComplex[] tab = new MyComplex[1600];
     
    }
    en une représentation en mémoire identique à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    {
    ...
    double[] tab_real = new double[1600];
    double[] tab_imag = new double[1600];
    }
    ou mieux

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    {
    ...
    double[] tab_reim = new double[3200];
     
    	public double getReal(int id){
    		return tab_reim [2*id];
    	}
     
    	public double getImag(int id){
    		return tab_reim [2*id+1];
    	}
    ..
    }
    Comme vous le savait surement, le temps d'exécution des opérations sur les matrices genre inversion et FFT2D sont fortement dépendantes de la représentation en mémoire des données. Donc la forme avec un tableau de real et un autre pour les imaginaires ou encore mieux une matrice avec de façon séquentiel le real et l'imaginaire sont la plus rapide en temps d'exécution car les données sont contiguës dans la mémoire et donc le temps d'accès est réduit.

    Une autre solution est de faire ma class complex nativement sous forme de vecteur. mais la lisibilité du code ne va pas être terrible. De plus ma class complex 'simple' est utilisée un peu partout. bon qui peut le plus peu le moins. un vecteur de complexe de 1 élément serait un complexe.

    Si vous avez d'autre idée je suis preneur.

    Citation Envoyé par tchize_ Voir le message
    Après, faudra voir tes algos pour qu'ils puissent travailler une page à la fois.
    Pas possible pour certain algo je dois prendre 2 fichiers pour en générer un troisième. Donc au minimum je dois avoir 3 représentations mémoire d'un fichier simultanément.

    Citation Envoyé par tchize_ Voir le message
    Ou alors passer à un jvm 64bits et une grosse mémoire
    Je devrais forcement y avait un jour. Toutefois mon plus gros problème actuellement c'est que j'ai du code sous 32bits (OpenGL) qui me demandera un peu de temps pour le convertir en 64bits). Mais cela est un autre pb.

    Sébastien.

  6. #6
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Citation Envoyé par <_oodTi96Tiboo_> Voir le message
    Concernant la référence à ajouter, y a t'il un autre moyen que de passer par l'utilisation de deux tableaux de double?
    Un seul tableau de doubles, comme tu le dis toi-même.
    Et puis, si c'est de la représentation 3D, c'est un des cas où les float se justifient, la précision double n'étant a priori pas indispensable.

    Citation Envoyé par <_oodTi96Tiboo_> Voir le message
    Le must pour moi serait une option magic donnée au compilation pour qu'il me transforme cela:
    Pas possible. Mais en réalité une classe comme celle proposée par tchize_ fait parfaitement le taf', en mettant juste les méthodes dont on a besoin. Essaie, tu verras.
    T'en a pas besoin de ta classe Complex individuel. Et même si c'était le cas, rien ne t'empêche de les créer à la volée à partir de la classe qui en contient plein, puis de les laisser disparaître quand tu as fini de t'en servir. (Bon ça bouffera quand même pas mal de CPU, même si au moins ça épargne la mémoire. Le mieux est de pas le faire.)

    Je recommande toutefois un seul tableau plutôt que deux.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

Discussions similaires

  1. Problème accès à une méthode d'un vecteur de classe
    Par sebdu94 dans le forum SL & STL
    Réponses: 3
    Dernier message: 30/04/2008, 23h00
  2. Organisation et optimisation de mes classes?
    Par Sylk dans le forum Langage
    Réponses: 4
    Dernier message: 30/11/2007, 10h22
  3. Optimisation d'une requête complexe
    Par ajuveneton dans le forum Langage SQL
    Réponses: 3
    Dernier message: 22/05/2007, 12h59
  4. vecteur de classe
    Par mohamed amine dans le forum Langage
    Réponses: 21
    Dernier message: 08/12/2006, 12h05
  5. [conception] vecteur de classes
    Par r0d dans le forum C++
    Réponses: 7
    Dernier message: 28/12/2005, 12h00

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