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

SL & STL C++ Discussion :

Pourquoi écrire des foncteurs ?


Sujet :

SL & STL C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut Pourquoi écrire des foncteurs ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    bool MaFonctionDeTri(const type & rl,const type & rr)
    {
    return rl < rr;
    }
     
    struct MonFoncteurDeTri
    {
    bool operator()(const type & rl,const type & rr)
    {
    return rl < rr;
    }
    };
    Je trouve la seconde écriture assez lourde et moins lisible.
    Dans quel cas est-il avantageux de l'utiliser lorsqu'on a un prédicat à passer en paramètre à une fonction de <algorithm> ?
    Merci pour vos retours d'expérience.

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    L'opérateur () d'une structure est résolu à la compilation et peut être inliné, alors qu'un pointeur sur fonction laissera toujours une indirection à l'exécution et empêchera toute optimisation.

    Dans certains cas cela a peu d'importance, dans d'autres cela en a énormément (utilise std::sort avec les deux, tu verras ).

    De plus, un foncteur peut porter un contexte (via ses données membres), ce que ne peut pas faire une fonction non-membre.

  3. #3
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    L'opérateur () d'une structure est résolu à la compilation et peut être inliné, alors qu'un pointeur sur fonction laissera toujours une indirection à l'exécution et empêchera toute optimisation.
    Les deux peuvent tout aussi bien être optimisés. Il me semble qu'à une époque il y avait un bug dans GCC qui lui empêchait d'optimiser les pointeurs de fonctions, mais y'a pas de raison pour que l'un s'optimise et pas l'autre.

    Utiliser un foncteur permet d'avoir autre chose qu'une fonction libre, et donc d'avoir en particulier un contexte et un état.
    Ça permet aussi de fournir différentes surcharges.

  4. #4
    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
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Les deux peuvent tout aussi bien être optimisés.
    C'est vrai en théorie. En pratique, il semble que ce soit bien plus simple dans un cas que dans l'autre.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    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 290
    Billets dans le blog
    2
    Par défaut
    L'utilisation d'un foncteur plutôt qu'une fonction libre peut être aussi agréable lorsque le code qu'il doit contenir est important et qu'il doit donc être découpé en sous-fonctions. Dans le cas d'une fonction libre, on va se retrouver avec tout un tas de fonctions libres. Personellement, je n'aime pas trop ça. Alors qu'avec un foncteur, on peut tout mettre dans un foncteur ( et éventuellement utiliser la ruse décrite ici ). Mais bon, là c'est assez subjectif.

  6. #6
    Membre émérite

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Par défaut
    Tout a fait. Je viens d'essayer avec VC2005 et GCC 3.4.4, dans les deux cas std::sort avec une fonction est environ deux fois plus lent que std::sort avec un foncteur.
    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
    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #include <ctime>
     
    inline bool fonction(int a, int b)
    {
      return a < b;
    }
     
    struct Foncteur
    {
      bool operator()(int a, int b) const
      {
        return a < b;
      }
    };
     
    int main()
    {
      int const n = 1000;
      int v0[n];
      for(int i = 0; i < n; ++i)
      {
        v0[i] = std::rand();
      }
      int v[n];
      for(int j = 0; j < 5; ++j)
      {
        std::clock_t t0 = std::clock();
        for(int k = 0; k < 10000; ++k)
        {
          std::copy(v0, v0 + n, v);
          std::sort(v, v + n, fonction);
        }
        std::cout << double(std::clock() - t0)/CLOCKS_PER_SEC << '\n';
      }
    }

  7. #7
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Sous VC++6 le foncteur est 4-5% plus rapide. Bien que ce soit peu significatif, c'est tout de même surprenant de ne pas avoir les mêmes performances !

    Bon ben va pour le foncteur() alors

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

Discussions similaires

  1. [VBA]écrire des formules en Access comme en Excel ?
    Par beegees dans le forum Access
    Réponses: 2
    Dernier message: 14/12/2005, 01h23
  2. [MFC] comment écrire des requêtes SQL
    Par kitsune dans le forum MFC
    Réponses: 9
    Dernier message: 27/09/2005, 15h23
  3. [Language][DAO]Pourquoi pas des Singletons ?
    Par le Daoud dans le forum Langage
    Réponses: 11
    Dernier message: 04/05/2005, 09h16
  4. Réponses: 9
    Dernier message: 05/04/2005, 09h39
  5. [eclipse] pourquoi ajouter des " import "
    Par keny dans le forum Eclipse Java
    Réponses: 3
    Dernier message: 06/10/2004, 14h20

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