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 :

Performance : String vs StringBuilder et accesseur vs accès direct aux champs


Sujet :

Langage Java

  1. #1
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2007
    Messages
    697
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 697
    Points : 1 241
    Points
    1 241
    Par défaut Performance : String vs StringBuilder et accesseur vs accès direct aux champs
    Bonjour,

    Je suis actuellement en train de travailler sur un programme qui demande une certaine optimisation : j'ai une fonction qui selon les cas doit concaténer entre 2 et 7 strings (selon les cas), l'usage de StringBuilder est-t-il approprié ? J'ai lu que dans certain cas le compilateur optimise de lui même en insérant un StringBuilder. Quel sont ces cas ?

    Doit-on suivre, aujourd'hui, la recommandation de ne pas essayer d’optimiser, de laisser le Javac faire sont boulot et de garder sont code le plus simple possible ?



    Autre point sur lequel je me pose des questions : l'accès a un champs via ses accesseurs plutôt que directement a-t-il un coup ? Encore une fois j'ai lu que dans les cas d'accesseur triviaux (ce qui est mon cas pour l'instant), le Javac va inliner les accesseurs. Mais que va-t-il se passer si je veux rendre mon programme multitreadable et donc ajouter synchronized sur certain accesseur ?

    Le Javac va-t-il inliner et ajouter un block synchronized(instance) autour de l'accès à la variable ?

    Pour information je travail actuellement avec la version 7 de Java mais j'aurai peut-être besoin de passer mon projet en JEE pour ajouter une GUI.

  2. #2
    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,

    Citation Envoyé par atha2 Voir le message
    Je suis actuellement en train de travailler sur un programme qui demande une certaine optimisation : j'ai une fonction qui selon les cas doit concaténer entre 2 et 7 strings (selon les cas), l'usage de StringBuilder est-t-il approprié ? J'ai lu que dans certain cas le compilateur optimise de lui même en insérant un StringBuilder. Quel sont ces cas ?
    Pourquoi une optimisation ? Cette "fonction" te cause des problèmes de performances ???


    Sinon dès que tu utilises l'opérateur + entre deux objets, tu utilises implicitement StringBuilder :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    String s = "Hello " + name;
     
    // Est équivalent à
     
    String s = new StringBuilder().append("Hello ").append(name).toString();
    L'intérêt d'utiliser StringBuilder directement permet d'éviter de multiple création d'objet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    String s = "Hello " + name;
    s += ", Hello " + anotherName;
    s += " and Hello " + yetAnotherName;
     
    // Est équivalent à
     
    String s = new StringBuilder().append("Hello ").append(name).toString();
    s = new StringBuilder().append(s).append(", Hello ").append(anotherName).toString();
    s = new StringBuilder().append(s).append(" and Hello ").append(yetAnotherName).toString();
    3 créations d'objets StringBuilder qui sont transformé en String à chaque fois...

    Là ca va c'est une petite chaine, mais si tu génère une très grosse chaine comme cela, cela peut vite devenir handicapant (en particulier dans une boucle).


    Bien sûr ce code peut tenir en une ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    String s = "Hello " + name 
        + ", Hello " + anotherName 
        + " and Hello " + yetAnotherName;
    Et là pas besoin de passer par StringBuilder car c'est fait automatiquement...


    Citation Envoyé par atha2 Voir le message
    Doit-on suivre, aujourd'hui, la recommandation de ne pas essayer d’optimiser, de laisser le Javac faire sont boulot et de garder sont code le plus simple possible ?
    Oh oui !!!!

    De toute manière, et quelque soit le langage, c'est une erreur de chercher à optimiser dans avoir au préalable bien cibler l'origine des mauvaises performances...


    Citation Envoyé par atha2 Voir le message
    Autre point sur lequel je me pose des questions : l'accès a un champs via ses accesseurs plutôt que directement a-t-il un coup ? Encore une fois j'ai lu que dans les cas d'accesseur triviaux (ce qui est mon cas pour l'instant), le Javac va inliner les accesseurs.
    Les accesseurs c'est chiant et lourd à écrire (quoi que on peut les générer automatiquement), mais c'est bien pratique lorsqu'on a besoin d'ajouter des contrôles...

    Par contre javac n'inline plus rien du tout depuis Java 1.2 !!!
    En effet désormais l'inlining est effectué par la JVM à l'exécution, ce qui permet des optimisation bien plus poussé selon le contexte...




    Citation Envoyé par atha2 Voir le message
    Mais que va-t-il se passer si je veux rendre mon programme multitreadable et donc ajouter synchronized sur certain accesseur ?

    Le Javac va-t-il inliner et ajouter un block synchronized(instance) autour de l'accès à la variable ?
    Je n'en ai concrètement aucune idée...

    Mais sinon tu voudrais faire comment : laisser le champs en accès libre et donc potentiellement non-synchronisé !?!?


    a++

  3. #3
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 214
    Points : 338
    Points
    338
    Par défaut
    D'ailleurs javac fait encore mieux si ces Strings sont constantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public static final String K0 = "AB";
    public static final String K = K0 + "CD";
     
    public String test(String name) {
      return K + " : " + name;
    }
    return ... est équivalent à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    return new StringBuilder().append("ABCD : ").append(name).toString();

  4. #4
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2007
    Messages
    697
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 697
    Points : 1 241
    Points
    1 241
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Salut,
    Pourquoi une optimisation ? Cette "fonction" te cause des problèmes de performances ???
    Non pas pour l'instant. Je suis encore en phase de développement. Mais je préfère m'informer avant pour éviter de me retrouver à modifier tout mon code.

    Citation Envoyé par adiGuba Voir le message
    L'intérêt d'utiliser StringBuilder directement permet d'éviter de multiple création d'objet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    String s = "Hello " + name;
    s += ", Hello " + anotherName;
    s += " and Hello " + yetAnotherName;
    C'est justement le genre de code que j'utilise (avec des if en plus pour les ligne 2 et 3, je ne pas donc pas tout mettre en une seule instruction. A part si l'utilisation de l’opérateur ternaire permet de tout transformer en un seul StringBuilder ?)

    Citation Envoyé par adiGuba Voir le message
    Là ca va c'est une petite chaine, mais si tu génère une très grosse chaine comme cela, cela peut vite devenir handicapant (en particulier dans une boucle).
    Un ordre de grandeur du nombre de concaténation à partir duquel ça pourrait devenir handicapant ?


    Citation Envoyé par adiGuba Voir le message
    Les accesseurs c'est chiant et lourd à écrire (quoi que on peut les générer automatiquement), mais c'est bien pratique lorsqu'on a besoin d'ajouter des contrôles...
    Ce n'est pas vraiment un problème je ne les écris jamais, je les génère.
    <HS>Le seul truc qui me dérange c'est qu'ils pourrissent la visibilité du code au détriment du code vraiment utile. D’ailleurs si quelqu'un connais un plugin Eclipse (voir IntelliJ ou Netbeans) pour les masquer, je suis preneur. Il y a bien les annotations @getter/setter de google mais bon apt augmente le temps de build de façon drastique (en tout cas c'est la cas avec androidannotation)</HS>

    Si je pose la question c'est que dans la plupart des exemples de création de DSL avec ANTLR (générateur de compilateur/interpréteur), les champs des classes sont lus/écrits directement. Ces exemples sont pourtant écrits par un Guru du domaine Terence Parr (créateur d'ANTLR) et tirés de son livre... Il doit bien avoir une raison ?

    Citation Envoyé par adiGuba Voir le message
    Par contre javac n'inline plus rien du tout depuis Java 1.2 !!!
    En effet désormais l'inlining est effectué par la JVM à l'exécution, ce qui permet des optimisation bien plus poussé selon le contexte...
    Toujours bon à savoir.

    Citation Envoyé par adiGuba Voir le message
    Mais sinon tu voudrais faire comment : laisser le champs en accès libre et donc potentiellement non-synchronisé !?!?
    Non non, je suis pas fou au point d'essayer (et échouer fatalement) de gérer la synchronisation à l'extérieur d'une classe (merci l'encapsulation au passage) : aujourd'hui mon programme est mono-thread.

    Je pose la question des performances car je pourrai avoir besoin (aujourd'hui je ne vois pas lequel mais qui sait ?) de rendre mon programme multi-thread auquel cas je serai bien content d'avoir mes accesseurs.

  5. #5
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2007
    Messages
    697
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 697
    Points : 1 241
    Points
    1 241
    Par défaut
    Citation Envoyé par -gma- Voir le message
    D'ailleurs javac fait encore mieux si ces Strings sont constantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public static final String K0 = "AB";
    public static final String K = K0 + "CD";
     
    public String test(String name) {
      return K + " : " + name;
    }
    return ... est équivalent à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    return new StringBuilder().append("ABCD : ").append(name).toString();
    C'est d'ailleurs une des principales raisons d'être des constantes (avec le faite quelle soit constante évidement) : remplacer tout ses usages par sa valeur, si sa valeur est connue à la compilation. Mais dans mon cas, un interpréteur, les strings sont récupérés pour la plupart dans le script ; à l'exécution.

  6. #6
    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 atha2 Voir le message
    C'est justement le genre de code que j'utilise (avec des if en plus pour les ligne 2 et 3, je ne pas donc pas tout mettre en une seule instruction. A part si l'utilisation de l’opérateur ternaire permet de tout transformer en un seul StringBuilder ?)
    Dans ce cas oui un StringBuilder serait plus propre...


    Citation Envoyé par atha2 Voir le message
    Un ordre de grandeur du nombre de concaténation à partir duquel ça pourrait devenir handicapant ?
    Je ne saurais dire. Ca dépend de la taille de la chaine et du nombre d'opération.

    Ce que je sais c'est que dans une boucle cela peut faire très très mal !!!
    Mais là on est plus dans une erreur de développement que dans de l'optimisation

    Citation Envoyé par atha2 Voir le message
    Si je pose la question c'est que dans la plupart des exemples de création de DSL avec ANTLR (générateur de compilateur/interpréteur), les champs des classes sont lus/écrits directement. Ces exemples sont pourtant écrits par un Guru du domaine Terence Parr (créateur d'ANTLR) et tirés de son livre... Il doit bien avoir une raison ?
    Aucune idée je ne maitrise pas trop le domaine.
    Maintenant dans du code généré cela ne me choque pas tant que cela : s'il y a besoin de modifier quoi que ce soit une régénération et hop c'est bon


    Citation Envoyé par atha2 Voir le message
    Je pose la question des performances car je pourrai avoir besoin (aujourd'hui je ne vois pas lequel mais qui sait ?) de rendre mon programme multi-thread auquel cas je serai bien content d'avoir mes accesseurs.
    Je n'ai jamais vu de problème de performance lié à l'utilisation de getter/setter...



    a++

  7. #7
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2007
    Messages
    697
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 697
    Points : 1 241
    Points
    1 241
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Maintenant dans du code généré cela ne me choque pas tant que cela : s'il y a besoin de modifier quoi que ce soit une régénération et hop c'est bon
    Sauf que dans ce cas là ce sont des classes qui ne sont pas générées, utilisées en complément des classes générées...

    Citation Envoyé par adiGuba Voir le message
    Je n'ai jamais vu de problème de performance lié à l'utilisation de getter/setter...
    Si je résume :

    • programme mono-thread : les accesseurs sont inlinés donc pas de problème de performance.
    • programme multithread : les accesseurs sont nécessaires.

    => Utilisation des accesseurs dans tous les cas !


    Merci pour toutes ces précisions

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

Discussions similaires

  1. Enlever accès direct aux pages avec struts
    Par Verboz dans le forum Struts 1
    Réponses: 7
    Dernier message: 09/05/2007, 15h29
  2. Gérer l'acces direct aux tables suivant les utilisateurs
    Par kristof33 dans le forum Sécurité
    Réponses: 2
    Dernier message: 02/03/2007, 08h11
  3. Interdire l'acces directe aux fichiers php
    Par Never dans le forum Apache
    Réponses: 4
    Dernier message: 04/12/2006, 21h00
  4. htaccess : interdire l'accès direct aux fichiers php
    Par Cédricss dans le forum Apache
    Réponses: 5
    Dernier message: 08/10/2006, 11h29
  5. [TOMCAT] Comment empêcher l'accès direct aux fichiers
    Par thomine dans le forum Tomcat et TomEE
    Réponses: 17
    Dernier message: 14/04/2005, 10h19

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