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

Java Discussion :

Performance et reflection


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2013
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Israël

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2013
    Messages : 131
    Par défaut Performance et reflection
    Bonjour tous le monde,

    A mon travail nous essayons de gagner du temps sur un processus de conversion de message texte en objet JAVA en fonction de leur provenance.
    Je m'explique :

    Si la provenance du message texte envoye provient de la societe A, alors nous chargeons le translator A. Si cela vient de la societe B alors nous chargeons le translator B. (Chaque message a ses specificites et donc chaque processus de conversion est legerement different). Pour etre plus precis ce sont des messages du protocole FIX (Financial Information eXchange).

    Nous chargeons les translators une fois au demarrage du serveur via une reflection en utilisant createInstance().

    Mon boss insiste sur le fait que les appels des differentes methodes d'un objet cree via reflection est beaucoup plus lent que les appels d'un objet cree via new.

    En cherchant sur le net, on peut en effet voir pas mal de petits tests montrant que l'instantiation prend beaucoup plus de temps en reflexion.

    1. Est ce egalement vrai pour les apppels d'un objet cree via cette reflection?
    2. Nous avons reexecuter un petit test trouver sur stackoverflow prouvant que la reflection etait beaucoup plus lent. Cependant sur mon PC de travail utilisant java 8, il n y a aucune difference de performance. Voici le code :

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    public class Main {
     
    public static void main(String[] args) throws Exception
    {
        doRegular();
        doReflection();
    }
     
    public static void doRegular() throws Exception
    {
        long start = System.currentTimeMillis();
        A a = new A();
        int a1 = 35;
        double d1 = 78.9;
        String s = "Yoni";
        for (int i=0; i<10000000; i++)
        {
     
     
            a.doSomeThing(a1, d1 ,s);
        }
        System.out.println(System.currentTimeMillis() - start);
    }
     
    public static void doReflection() throws Exception
    {
        long start = System.currentTimeMillis();
        B a = (B) Class.forName("B").newInstance();
        int a1 = 35;
        double d1 = 78.9;
        String s = "Yoni";
        for (int i=0; i<10000000; i++)
        {
     
     
            a.doSomeThing(a1, d1 ,s);
        }
        System.out.println(System.currentTimeMillis() - start);
    }
    }
    Les classes A et B sont exactement les meme classes. Nous avons tester ce test avec l'instantiation dans la boucle et a l'exterieur de la boucle. Le second cas etait pour tester uniquement les appels de methode d'un objet cree via reflection.

    Nous avons execute plusieurs fois ce petit programme mais il n y a quasiment aucune difference de performance :

    Output :
    54418
    54213


    Quelqu'un peut il faire de l'ordre dans ma tete ?

    Merci

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

    Absolument pas.

    Utiliser la réflectivité est moins performant que faire la même chose sans réflectivité, c'est vrai. Encore que c'est surtout à cause des opérations supplémentaires qui sont faites au début et à la fin d'une opération réflective et dont on a pas besoin sinon. Ce n'est pas la réflectivité qui rend magiquement toutes les opérations moins performantes parce qu'elles sont faites pendant qu'on fait de la réflectivité.
    Autrement dit, la perte de performance est un temps fixe. Et en conditions réelles, il est assez rare que les opérations qu'on fait soient tellement rapides que la perte de temps en réflectivité puisse se voir. Parce que bon, quand on perd une demi-seconde sur 24 heures d'utilisation, eh ben ce n'est pas malin de s'y intéresser.

    Mais passons, oui la réflectivité est moins performante que la même chose sans réflectivité.
    Par contre, une fois qu'un objet a été créé, ça n'a aucune incidence qu'il ait été créé par réflectivité ou autrement. L'objet est représenté pareil en mémoire, sa classe aussi, ce qui en décide l'accès aussi.

    Pour finir, le test que tu as essayé est biaisé : doReflection() est appelée après doRegular(), ce qui veut dire qu'elle profite des optimisations faites par le compilateur JIT et par les différents chargements paresseux et mises en cache, alors que doRegular() a dû se taper tout le boulot, elle. Un test de ce genre marcherait déjà mieux si les deux méthodes étaient dans des programmes séparés avec chacun son main() lancé manuellement.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Même avis

    Pourquoi l'exécution d'une méthode d'un objet créé par réflexion serait plus lente que si l'objet avait été créé par new ?
    Ça n'a pas de sens, une fois la classe en mémoire, c'est le même code...
    Là, c'est de l'ordre de la légende urbaine
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 326
    Billets dans le blog
    12
    Par défaut
    Au niveau de ton doReflection(), appelle ton doSomething() par reflection grâce à Method (reste dans le scope de ton for), tu sentiras surement mieux la différence au niveau de performances.
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  5. #5
    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
    Citation Envoyé par Yonito Voir le message
    Mon boss insiste sur le fait que les appels des differentes methodes d'un objet cree via reflection est beaucoup plus lent que les appels d'un objet cree via new.
    Et bien c'est complètement faux, et ce n'est pas là que tu gagnera du temps. Et si ton boss n'est pas d'accord, qu'il m'appelle.

    Par contre ce qui "pourrait" être vrai, si l'instanciation se fait par un mécanisme comme CDI ou EJB, tu pourrais te faire injecter un proxy à la place de l'instance réelle et là, effectivement, chaque appelle impliquerait la surcharge lié au proxy.


    Si tu veux vraiment gagner du temps sur l'application, la première chose à faire c'est un état des lieux en identifiant les point chaud de l'application, les vrai, pas les supposé juste en regardant le code. Et pour faire ça, on utilise un profiler, qui va soit travailler par coups de sonde, soit instrumenter tout le code pour faire une mesure précise. Le premier peux se faire en prod, le deuxième ralentit tellement l'application pendant la mesure qu'il faut parfois le faire tourner sur le coté avec des données de test.

  6. #6
    Membre expérimenté
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2013
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Israël

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2013
    Messages : 131
    Par défaut
    Merci tous le monde pour vos differentes reponses.

    Je vais analyser cela et reviens vers vous rapidement pour cloturer le sujet si besoin n'est plus.

    Si tu veux vraiment gagner du temps sur l'application, la première chose à faire c'est un état des lieux en identifiant les point chaud de l'application, les vrai, pas les supposé juste en regardant le code. Et pour faire ça, on utilise un profiler, qui va soit travailler par coups de sonde, soit instrumenter tout le code pour faire une mesure précise. Le premier peux se faire en prod, le deuxième ralentit tellement l'application pendant la mesure qu'il faut parfois le faire tourner sur le coté avec des données de test.
    Est ce que tu peux me guider sur cela please, j'ai demande a mes collegues et tous leurs tests sont via des test java avec des system.out de temps. Connais tu un "programme" qui permet de faire ces mesures ? De preference gratuit.

    merci

  7. #7
    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
    Les sysout c'est pas très propre dans le code et c'est inutile pour mesurer. Ca ne mesure que ce que tu veux mesurer et tout le problème du profiling, c'est qu'on ne sait pas à l'avance ce qu'on doit mesurer. Si on le sait déjà, on n'a plus besoin de profiler, on corrige

    visualvm pour commencer est assez simple à prendre en main. https://visualvm.java.net/
    eclispe a aussi un profiler dans TPTP http://www.eclipse.org/tptp/
    Après il y a des solution commerciales bien balaises mais bon, faut payer les licenses. Très utiles aussi quand tu cherche l'origine d'une fuite mémoire.

  8. #8
    Membre expérimenté
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2013
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Israël

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2013
    Messages : 131
    Par défaut
    Ok merci des propositions,

    j'ai demande a mes superieurs et aparament ils utilisent en production JProfiler 8 dont la societe possede une licence. Je vais essayer de creuser dans cette direction.

    Merci pour votre aide.

  9. #9
    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
    j'ai utilisé ça par le passé, c'est pas mal foutu du tout.

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

Discussions similaires

  1. [Performances] Foreach ou reflexion ?
    Par anthyme dans le forum C#
    Réponses: 4
    Dernier message: 11/07/2007, 10h54
  2. [maintenance][performance] Que faire comme maintenance ?
    Par woodwai dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 06/11/2003, 15h39
  3. [ POSTGRESQL ] Problème de performance
    Par Djouls64 dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 26/05/2003, 16h18
  4. [JDBC][connexion persistante] performances avec JDBC
    Par nawac dans le forum Connexion aux bases de données
    Réponses: 6
    Dernier message: 06/05/2003, 10h37
  5. performance entre 3DS, ase, asc ...
    Par amaury pouly dans le forum OpenGL
    Réponses: 3
    Dernier message: 24/03/2003, 11h41

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