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 :

Comment minimiser les appels à l'opérateur new


Sujet :

Langage Java

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 2
    Points : 2
    Points
    2
    Par défaut Comment minimiser les appels à l'opérateur new
    Bonjour à tous,
    Je suis un développeur C++ actuellement en train d'apprendre Java (principalement pour de la prog Android).

    Ce langage est réellement génial, mais y a quelque chose que j'ai du mal à assimiler:

    Je comprend bien que l'appel à l’opérateur new est moins coûteux en java qu'en C++ (même si apparemment cela dépend de la JVM) mais ce que je ne comprend pas, c'est qu'il ne soit simplement pas possible d'allouer des objets sur la pile.

    Ex:

    Si en C++ j'ai une structure de ce type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct SVertex
    {
       float x;
       float y;
       float z;
       float u;
       float v;
    };
    je peux écrire cela dans une fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void fnc( )
    {
        SVertex vertexArray[256];
    }
    l'allocation et la de-allocation n'ont alors quasiment aucun impact étant donnée que le tableau est alloué sur la pile.

    Seulement en Java, je ne peux (à ma connaissance) pas faire cela, il ne me reste que l'opérateur new comme alternative:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void fnc( )
    {
        SVertex[] vertexArray = new SVertex[256];
    }
    Cela n'a certainement aucun impact si ce code n'est réalisé que lors du démarrage de l'appli, mais si cette fonction est appelée 200 fois par frame (dans le cas d'une appli graphique) cela doit être plus pénalisant.


    Donc en somme, ma question est la suivante:
    En java, somme nous obligé d'utiliser l'opérateur new pour crée des objects qui serviront de manière temporaire lors d'un phase de calcul ou autre ?
    Est il possible d'écrire de nouvelles "primitives" en java (comme float ou int )


    Quel sont vos conseil à ce sujet ??

    Merci a vous tous !!

    Cordialement,
    Clément Vidal

  2. #2
    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
    non, en java, on ne pense pas comme en C. De plus, c'est bien joli d'allouer sur la pile, mais au final, on ne sais rien faire de ces objets:

    par question de les passer à d'autres méthode autrement que par copie (sous peine que de l'autre coté on garde une référence dessus qui dure plus longtemps que l'appel à fnct) et la copie, ca prend du temps. Et dans les méthodes de l'objets, il ne peux pas s'autoréférencer nulle par (pour le même problème) -> en java on a supprimé simplement les objets sur la pile, et on fait avec et, effectivement, new ne consomme que des clopinette. C'est plus le code à l'intérieur du constructeur qui va consommer

    Maintenant, simplement, on évite de créer 500.000 objets par secondes, sinon, le GC, il va pas apprécier, lui C'est une question d'optimisation de ses algorithmes.

    Et non, on ne peux pas créer des type primitifs "custom".

    Edit: pour les tableaux tu as aussi cette notation

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SVertex[] vertexArray = {null,null,null,null}
    mais mon petit doigt me fait croire que le compilateur va quand même tapper un new quelque part

  3. #3
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 547
    Points : 21 602
    Points
    21 602
    Par défaut
    De toute façon, si le but est de ne pas créer un nouveau tableau sans arrêt, il suffit d'en créer un seul et de le réutiliser... C'est finalement la même chose que la pile, sauf qu'il faut prévoir à l'avance la taille et le nombre nécessaire des tableaux.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  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
    Citation Envoyé par thelvin Voir le message
    De toute façon, si le but est de ne pas créer un nouveau tableau sans arrêt, il suffit d'en créer un seul et de le réutiliser... C'est finalement la même chose que la pile, sauf qu'il faut prévoir à l'avance la taille et le nombre nécessaire des tableaux.
    Hmm... Perso je trouve cela assez casse-gueule ! :/

    D'une part cela complique la méthode (on doit "effacer" les données précédentes), mais cela augmente aussi la durée de vie de ces objets inutilement, et cela rend le code non thread-safe...



    Le "coût" de la création du tableau est surement moins important !
    Surtout que si l'objet est bien limité à la méthode, il pourra être nettoyé rapidement par le GC. Le coût est surement extrêmement faible...

    Mieux, avec l'escape-analysis il pourra carrément subir un "inline" extrême qui pourrait aboutir à une allocation nulle !




    @ClementVidal : Évites de penser en C/C++. C'est une erreur qui te fera faire des bêtises. Ce qui est vrai en C/C++ ne l'es pas forcément en Java, et inversement.

    Si tu as des problèmes de perf, poste le code en question qu'on en discute, mais sinon ne cherche pas à optimiser pour optimiser. La JVM le fait bien mieux que toi...



    a++

  5. #5
    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
    Citation Envoyé par adiGuba Voir le message
    Mieux, avec l'escape-analysis il pourra carrément subir un "inline" extrême qui pourrait aboutir à une allocation nulle !
    Exact Cet article d'ailleurs (en anglais)
    http://www.java.net/external?url=htt...-jtp09275.html

    mentionne au passage qu'un malloc en C est environ 3 fois moins performant qu'un new en java. Il y est aussi précisé le principe de l'escape analysis qui fait qu'un objet peut être alloué par la jvm sur le stack voir carrément directement dans les registres (l'extrême dont par adiguba)

  6. #6
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 547
    Points : 21 602
    Points
    21 602
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Le "coût" de la création du tableau est surement moins important !
    Surtout que si l'objet est bien limité à la méthode, il pourra être nettoyé rapidement par le GC. Le coût est surement extrêmement faible...
    J'ai déjà mesuré, il y a de nombreux cas où le coût est largement plus important que la légère complexité ajoutée. Déjà non, il n'y a rien à nettoyer, les valeurs non initialisées ne doivent pas être lues.

    Quant à la durée de vie, elle doit être attachée à un contexte de calcul. Elle est rallongée puisque le but est d'éviter de passer son temps à allouer/désallouer. Mais pas plus que nécessaire.

    Pour le multithreading, de toute façon on fonctionne en monothreadé.


    Bon, cette objection étant prononcée, il arrive un moment où on doit juste accepter que le fonctionnement de Java le rende parfois moins optimal que d'autres langages, et c'est comme ça. Le temps perdu par rapport à C est surtout perdu en accès tableaux, et pour ça il n'y a rien à faire.

    Citation Envoyé par adiGuba Voir le message
    Mieux, avec l'escape-analysis il pourra carrément subir un "inline" extrême qui pourrait aboutir à une allocation nulle !
    Ça c'est possible en effet, mais il n'y en avait pas quand j'avais essayé. Je dirais qu'on est dans un cas où il faut tester et mesurer.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    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
    @thelvin : il est tout à fait possible que cela s'avère utile dans certains cas. Mais il faut détecter le problème et bien l'analyser avant de mettre en place quelque chose comme cela...


    Là j'ai plus l'impression que ClementVidal recherche une solution de remplacement à utiliser systématiquement. Et c'est justement ce qu'il faut éviter !


    a++

  8. #8
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 705
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur java, access, sql server
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 705
    Points : 4 783
    Points
    4 783
    Par défaut questions d'allocation mémoire
    Puisqu'on est dans les questions de coût de création d'objet, je me suis toujours demandé si, dans une boucle, il vaut mieux faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MaClasse monObjet;
    for (i=0; i<100; i++){
        monObjet = new MaClasse();
    }
    plutôt que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (i=0; i<100; i++){
        MaClasse  monObjet = new MaClasse();
    }
    en disant que MaClasse est un POJO quelconque.
    Labor improbus omnia vincit un travail acharné vient à bout de tout - Ambroise Paré (1510-1590)

    Consulter sans modération la FAQ ainsi que les bons ouvrages : http://jmdoudoux.developpez.com/cours/developpons/java/

  9. #9
    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
    @Népomucène : c'est strictement identique puisque la zone mémoire occupé par la référence sera stocké dans la pile. Reste donc les new à chaque itération...


    Perso je dirais que le second code est plus propre, car il limite mieux le scope des variables.


    a++

  10. #10
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 705
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur java, access, sql server
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 705
    Points : 4 783
    Points
    4 783
    Par défaut
    @adiGuba

    Merci
    Labor improbus omnia vincit un travail acharné vient à bout de tout - Ambroise Paré (1510-1590)

    Consulter sans modération la FAQ ainsi que les bons ouvrages : http://jmdoudoux.developpez.com/cours/developpons/java/

  11. #11
    Membre chevronné
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Points : 1 855
    Points
    1 855
    Par défaut
    dans le même ordre d'idée la raison pour laquelle il vaut mieux écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    for(int ix=0 ; ix <max, ix++) {
    }
    est que la variable ix est purement locale à la boucle ....
    donc pas d'effet de bord sur un index en sortie de boucle ...
    J'ai des principes: je peux toujours trouver une bonne raison pour les contredire .... mais j'ai des principes!
    (mon excellent bouquin sur Java : https://eska-publishing.com/fr/livre...822407076.html)

Discussions similaires

  1. Réponses: 3
    Dernier message: 28/02/2015, 19h51
  2. Comment organiser les appels réseau pour transmettre des mouvements fluides ?
    Par khayyam90 dans le forum Développement 2D, 3D et Jeux
    Réponses: 13
    Dernier message: 07/11/2007, 15h18
  3. Réponses: 3
    Dernier message: 18/10/2007, 13h26
  4. Réponses: 10
    Dernier message: 23/06/2007, 17h13
  5. Réponses: 2
    Dernier message: 03/10/2006, 19h14

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