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

C++ Discussion :

Passer des types simples en paramètres


Sujet :

C++

  1. #1
    Membre expérimenté
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Points : 1 685
    Points
    1 685
    Par défaut Passer des types simples en paramètres
    Bonjour,

    j'aimerais savoir s'il y a une différence de performance entre ces prototypages pour une seule et même tache :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void fun(size_t);
    void fun(size_t const);
    void fun(size_t const&)
    Je crois me souvenir avoir lu dans le livre d'Alexandrescu que la deuxième solution est plus efficace que la troisième mais je ne vois pas vraiment pourquoi.

    J'ai une deuxième question connexe concernant les fonctions templates :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template<typename T> void fun(T const&);
    Dans le cas où T peut aussi bien être un type simple qu'un objet, quelle solution préconisez-vous pour forcer les types simples à ne pas être passés par référence mais par valeur?

    Merci d'avance pour votre aide et vos conseils!

  2. #2
    Membre confirmé Avatar de Nhaps
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2011
    Messages
    350
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2011
    Messages : 350
    Points : 600
    Points
    600
    Par défaut
    Citation Envoyé par Aleph69 Voir le message
    Dans le cas où T peut aussi bien être un type simple qu'un objet, quelle solution préconisez-vous pour forcer les types simples à ne pas être passés par référence mais par valeur?
    Bonjour,

    Pourquoi ne pas passer les types simples par référence ?

    EDIT : sinon j'aurai dit pour ta première question que la 3eme solution est la meilleur car on m'a toujours dit par exemple pour un setteur que le prototype soit comme ta 3eme solution évitant ainsi une duplication en mémoire de ce que tu passe en paramètre.

  3. #3
    Membre expérimenté
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Points : 1 685
    Points
    1 685
    Par défaut
    A cause de ce qui est dit plus haut : dans le cas particulier des types simples, j'ai cru comprendre qu'il valait mieux passer par valeur que par référence. Mais je me trompe peut-être.

  4. #4
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 475
    Points
    11 475
    Billets dans le blog
    11
    Par défaut
    Pour avoir un passage de paramètre optimal, tu peux utiliser ceci :
    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
    //! Struct used to select best way to put type in parameter : 'value' or 'const reference'
    template <typename T>
    struct CallTraits
    {
    	template <typename U, bool Big> struct CallTraitsImpl;
    	//! Struct used to select 'const reference' parameter type
    	template <typename U>
    	struct CallTraitsImpl<U, true>
    	{
    		typedef const U & Type;
    	};
    	//! Struct used to select 'value' parameter type
    	template <typename U>
    	struct CallTraitsImpl<U, false>
    	{
    		typedef U Type;
    	};
    	typedef typename CallTraitsImpl<T, (sizeof( T) > 8)>::Type ParamType;
    };
    Du coup, dans ta fonction, ça donnerait ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void fun(CallTraits<size_t>::ParamType p_param)

  5. #5
    Membre expérimenté
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Points : 1 685
    Points
    1 685
    Par défaut
    Merci pour cette solution élégante. Je pense même qu'il est possible de cacher le booléen aux utilisateurs en passant par une autre classe de trait déterminant si un type donné est simple ou pas.

    J'ai quelques questions par rapport à cette solution :

    1. le test sizeof( T) > 8 est-il pérenne?
    2. je vois que les types simples sont passés par valeur non constante : pourquoi?

  6. #6
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 475
    Points
    11 475
    Billets dans le blog
    11
    Par défaut
    Cette solution tient uniquement compte de la taille.
    Je pense que c'est la question la plus importante lors du passage d'un paramètre, la copie est à mes yeux négligeable pour une taille <= 8. Au-dessus aussi, dans une certaine limite, mais 8 est une limite qui permet à tous les types basiques de passer.

    EDIT : A la question de la pérennité du sizeof( T) > 8, je dirais oui, jusqu'à ce qu'on passe à des processeurs 128 bits.

  7. #7
    Membre expérimenté
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Points : 1 685
    Points
    1 685
    Par défaut
    Super, merci!

  8. #8
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 265
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 265
    Points : 6 686
    Points
    6 686
    Billets dans le blog
    2
    Par défaut
    Veuillez me pardonner de m'immiscer ainsi dans la discussion, mais concrètement, dans quel cas peut-il être préférable de passer un argument par valeur que par référence constante?

  9. #9
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 475
    Points
    11 475
    Billets dans le blog
    11
    Par défaut
    Préférable ? Je dirais aucun.
    Commode ? Je dirais pour tous les types basiques.
    Personnellement je passe les types basiques par valeur, par habitude, et parce que je pense ne rien gagner à les passer par référence.
    D'ailleurs, je pense que passer par référence une variable dont la taille est inférieure à la taille d'une adresse (bool, char, short sur du 32 bits, int, long, float sur du 64 bits) n'est vraiment pas utile car sur la pile une adresse prendra plus de place. C'est ridiculement négligeable, j'en conviens, mais c'est tout de même là.

  10. #10
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    La question pertinante se pose sur la taille des données passées, une référence ca a beau être un alias sur quelque chose qui existe déjà, ca n'en a pas moins une taille. Donc c'est préférable dès que sizeof(T) < sizeof(T&) (le const ne change rien à la taille).

    Dans le cas d'égalité c'est au choix, mais entre référence constante et copie, la copie offre bien plus de libertés (on peut en faire ce qu'on veut) donc personnelement j'aurais tendance à prendre la copie en cas d'égalité.

    NB: Le plus simple et de comparer à sizeof(T&) et pas à une valeur fixé, les tailles (sauf exception, char par exemple) dépendent de l'architecture / de l'implémentation.

    Et avec le C++2011, ca donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    template<class T>
    struct param
    {
      typedef typename
        std::conditional<sizeof(T) <= sizeof(T*), T, const T&>::type
        type;
    };
    Par contre ce n'est pas à utiliser partout, ca bloque une partie du processus de déduction automatique des paramètres template.

  11. #11
    Membre expérimenté
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Points : 1 685
    Points
    1 685
    Par défaut
    Salut Flob90,

    est-ce que tu pourrais développer ce dernier point?

    Citation Envoyé par Flob90 Voir le message
    Par contre ce n'est pas à utiliser partout, ca bloque une partie du processus de déduction automatique des paramètres template.
    Est-ce que tu connaitrais un exemple concret ou les cas où ça se produit?

  12. #12
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    template<class T>
    void foo(typename param<T>::type)
    { }
     
    foo(0); //ne compile pas
    foo<int>(0); //compile
    Alors que si j'avais mis const T& (ou T) à la "main", ca aurait compilé. Le système de déduction automatique des paramètres template est coupé à cause du typename. Le compilateur peut chercher à "matcher" les paramètres template pour qu'il correspondent au type passé en paramètre (même si le motif est MaClassTemplate<T,U,...>), mais il ne peut pas le faire pour un type définie dans une classe template.

  13. #13
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Passer par référence peut bloquer le processus d'analyse d'aliasing du compilateur, et donc baisser les performances. On m'a rapporter un vrai programme manipulant plein de strings dont les perfs se sont améliorées en passant les string par copie...

  14. #14
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 265
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 265
    Points : 6 686
    Points
    6 686
    Billets dans le blog
    2
    Par défaut
    Très intéressant tout ceci.
    Ce problème que vous pointez sur le processus d'aliasing, c'est valable uniquement dans le cas de variables templates ou dans le cas général également?

  15. #15
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Je ne pense pas que les templates puissent avoir un impact sur ce sujet, c'est une optimisation qui à lieu à un autre moment. L'idée de base est la suivante (mais en pratique, c'est bien plus compliqué) :
    Dans le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    string maChaineGlobale;
    void g()
    {
        maChaineGlobale = "Tutu";
    }
     
    void f(string s)
    {
      if (s=="Toto") {cout << "toto";}
      g();
      if (s=="Toto") {cout << "toto";}
    }
    Il peut optimiser le code de f, car il sait que s ne peut pas être modifiée par l'appel de g.

    Si maintenant f prend en paramètre une référence, même constante, il ne peut plus faire cette optimisation, sauf s'il peut prouver que maChaineGlobale n'est jamais passée en paramètre à f.

  16. #16
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Citation Envoyé par Aleph69 Voir le message
    Salut Flob90,

    est-ce que tu pourrais développer ce dernier point?



    Est-ce que tu connaitrais un exemple concret ou les cas où ça se produit?

    boost::call_traits pour eviter de reinventer la roue.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 03/03/2014, 21h51
  2. Passer des types primitifs par référence constante ?
    Par FluidBlow dans le forum Langage
    Réponses: 2
    Dernier message: 24/12/2010, 15h43
  3. Passer des objets complexes en paramètres
    Par davet dans le forum Struts 2
    Réponses: 2
    Dernier message: 06/11/2008, 21h28
  4. Passer des objets Java en paramètre
    Par ruby_robber dans le forum BIRT
    Réponses: 3
    Dernier message: 23/06/2008, 12h30
  5. [SOAP] Passage des types imposés en paramètres
    Par Guybrush113 dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 08/10/2007, 09h34

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