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 C++ Discussion :

Comment se passer de 'virtual' dans mon cas


Sujet :

Langage C++

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2014
    Messages : 5
    Points : 3
    Points
    3
    Par défaut Comment se passer de 'virtual' dans mon cas
    Bonjour à tous

    J'ai codé une lib statique de calcul scientifique spécifique à mes travaux (aucune lib là dessus ne préexistait a priori car mon projet est très spécifique à mon application).
    Je ne vais pas entrer dans les détails, mais cette lib est constituée de plusieurs classes dont une classe A_ qui est abstraite, ie avec des méthodes déclarées sous la forme virtual (...) = 0 ; . Par ailleurs, toujours dans cette lib, j'ai une autre classe C dont un membre est un pointeur sur A_ (genre A_ *ptrA_). Des fonctions membres de C appellent des méthodes virtuelles pures de A_ via le pointeurs (les appels sont codés ptrA_ -> MethodeAbstraite(...) . Je précise que le ptrA_ pointe sur un espace alloué dynamiquement dans le constructeur de C via un "clone pattern" appliqué sur un objet dérivé de A_, passé en argument dans le constructeur de C... Voir le code pour comprendre ce que je veux dire.

    Lorsque je veux utiliser les fonctionnalités de ma lib, je dois donc déclarer une classe B, dérivée de A_ afin de spécifier les méthodes qui sont virtuelles pures ... L'avantage de ce procédé est que j'utilise l'héritage et que surtout, c'est très simple à utiliser car le code de calcul s'adapte à n'importe quel type dérivé de A_ ... suffit juste de définir les quelques méthode virtuelles pures. Cette façon de faire s'avère très pratique pour monter des projets où plusieurs personnes sont impliquées.

    Voici un exemple minimum pour illustrer ma description
    Voici ce que j'ai codé dans ma lib :

    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
     
    // Classe abstraite
    class A_
    {
    public:
     virtual double F() const = 0;
     virtual A_* Clone() const = 0;
     // + d'autres méthodes virtuelles pures 
    // + des méthodes non virtuelles
     
    // des membres
    };
     
     
    class C
    {
    // Une classe qui contient un pointeur de type A_*
    public:
    // Constructeur
    C(A_* ptrObjectDerive)
    {
     ptrA_ = ptrObjetDerive.Clone(); // Appelle le ctr de recopie et alloue dynamiquement la  mémoire pointée par ptrA_
    // etc ...
    }
    void Fonction()
    {
    //Une fonction qui appelle ptrA_->F() plus de 100000 fois ...
    } 
    protected:
    A_ *ptrA_;
    double x;
    //etc...
    };

    Lorsque je veux utiliser ma lib je dois faire cela :
    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
     
    // Classe dérivée de A_
    class B:public A_
    {
    // définition du constructeur, du constructeur de recopie etc...
    // [....]
     
    // Le clone pattern
     virtual A_* Clone() const
    {
     return new A_(*this);
    }
    virtual double F () const
    {
    // Spécialisation de F ici ...
    }
     
    };
    Le prog principal :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    // main.cpp
    // etc...
     
    B ObjetB(...) // Création d'un objet B
    C ObjetC(&ObjetB, ...) //Création d'un objet C ayant un objet de type pointeur_sur_B en paramètre (+ d'autres paramètres)
    ObjetC.Fonction(); // fonction qui va appeler 100000 fois une méthode codée en virtual
    Ma lib fonctionne correctement, mais j'ai lu que travailler avec des virtual était gourmand en temps car la détermination de la méthode à appeler est résolu non pas à la compilation mais à l'exécution. Dans ma situation, j'appelle une méthode virtual des centaines de milliers de fois ... donc quelque chose me dit qu'il est possible de faire un truc bien + performant ... De plus, comme l'atteste le programme principal, on sait dès la compilation quelle fonction F() devra être utilisée, donc il est inutile d'attendre l'exécution pour savoir si je dois appeler telle ou telle méthode membre F. Donc je me dis qu'il y a un sacré manque à gagner ... non ?

    D'où ma question : Est-il possible de re-concevoir autrement le pb tout en gardant cette souplesse d'utilisation (juste spécifier quelques fonctions tout en puissant utiliser ce qui est déjà codé dans la classe abstraite A_) ? Et aussi, en n'utilisant pas de virtual ? Je viens de lire quelques tutos sur la méta programmation avec les 'template' qui cherche à faire bosser le compilateur avant tout ... ça me parait vraiment très intéressant pour mon pb où la rapidité est critique, non ? Sauriez-vous m'aiguiller vers une approche adéquate ?

    Merci à vous

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Salut,

    Il est, en effet, possible de changer entièrement son fusil d'épaule, mais cela nécessitera (peut être) de grosses modifications au niveau de ton code

    Je te proposerais donc de changer ton schéma de pensée et de ne plus réfléchir en termes de services rendus par tes classes, mais en fonction de l'utilisation qui est faite de tes données.

    Autrement dit, jusqu'à présent, tu as suivi un raisonnement proche de
    Toutes mes classes doivent être clonables, j'expose donc un service qui permet d'obtenir le comportement requis, adapté au type réel de la donnée qui doit être clonée.
    C'est, typiquement, le schéma de pensée que l'on essaye de respecter en programmation orientée objet

    Celui que je te propose d'utiliser est de te dire :
    je ne sais pas exactement quel sera le type de la donnée que je vais manipuler, mais je sais par contre parfaitement comment je vais manipuler cette donnée
    Ce schéma de pensée te permettra d'aborder tes problème sous un autre angle : celui de la programmation générique

    Tu pourrais donc, par exemple, créer une classe qui manipule "n'importe quel type de données" sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template <typename Data>
    class DataManipulator{
        public:
            inline void execute(Data const & data) const{
                data.computeMe();
            }
    };
    Grâce à cela, tes différentes données ne doivent même plus forcément avoir une classe de base commune qui déclarerait une fonction virtuelle void computeMe() const;. La seule obligation est que, quel que soit le type mis à la place de Data, il expose effectivement une fonction (qui ne doit pas forcément être virtuelle) void computeMe() const;Alors, bien sur, il arrivera parfois que, pour un type de donnée particulier (appelons le SpecificData pour l'exemple), tu ne veuille pas invoquer computeMe, mais plutot une fonction doSomething(), par exemple.

    Tu pourras sans aucun problème fournir ce que l'on appelle une spécialisation totale de la fonction sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<>
    void DataManipulator<SpecficData>::execute(SpecificData const & data) const{
        data.doSomething();
    }
    qui permettra de s'assurer que c'est bel et bien la fonction doSomething qui est appelée et non la fonction computeMe (qui n'existe peut être pas d'ailleurs ).

    Evidemment, comme il n'y a plus, a priori, de classe de base commune à tes différents types de données, il n'y a plus aucune raison de les rendre clonables. Et il devient totalement impossible de déclarer un pointeur du type de la classe de base, vu qu'il n'existe purement et simplement plus de classe de base

    Mais il est possible de fournir une généralisation de tout ce qui manipule les données.

    Par exemple, tu pourrait avoir une classe qui n'utilise (soyons attentifs aux termes : je dis utiliser dans le sens où elle dispose d'une membre du type envisagé, à mettre en parallèle avec le terme manipuler que j'avais utilisé pour DataManipulator ) qu'une seule donnée sous une forme proche de
    t
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    emplate <typename Data>
    class OneDataHolder{
        public:
            OneDataHolder(Data const & data):data_(data){}
            void doSomething() const{
                DataManipulator<Data>().execute(data_);
            }
        private:
            Data data_;
    };
    ou une classe qui utilise deux données de type potentiellement identiques:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template <typename D1, typename D2 = D1>
    class TwoDataHolder{
        public:
            TwoDataHolder(D1 const & data1, D2 const & data2):data1_(data1),data2_(data2){}
            void doSomething() const{
                DataManipulator<D1>().execute(data1_);
                DataManipulator<D2>().execute(data2_);
            }
        private:
            D1 data1_;
            D2 data2_;
    };
    Et nous pourrions bien sur ne pas nous en arrêter là, mais tu as compris le principe
    Imaginons maintenant que nous ayions une classe Data1 et une classe Data2 qui représentent chacun un de tes concepts spécifiques. Nous partons du principes que chaque classe expose bel et bien une fonction publque void computeMe() const

    Avec les deux classes OneDataHolder et TwoDataHolder dont je viens de parler, tu as droit au total à pas moins de six possibilités distinctes sans avoir à rajouter quoi que ce soit. La classe OneDataHolder peut aussi bien manipuler un objet de type Data1 qu'un objet de type Data2:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int main(){
        Data1 data1;
        OneDataHolder<Data1> d1(data1);
        d1.execute();
        Data2 data2:
        OneDataHolder<Data2> d2(data2);
        d2.execute();
        return 0;
    }
    Et avec TwoDataHolder, tu as les quatre autre possibilités : utiliser deux fois le type Data1, utiliser deux fois le type Data2, utiliser le type Data1 pour la première donnée et le type Data2 pour la deuxième et enfin utiliser le type Data2 pour la première donnée et le type Data1 pour la deuxième (si tant est que le sens ait une importance

    Cela pourrait prendre la forme de
    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
    int main(){
        Data1 data1a;
        Data1 data1b;
        TwoDataHolder<Data1> d1(data1a, data1b);
        d1.execute();
        Data2 data2a;
        Data2 data2b;
        TwoDataHolder<Data2> d2(data2a, data2b);
        d2.execute();
        TwoDataHolder<Data1, Data2> d3(data1a, data2b);
         d3.execute();
        TwoDataHolder<Data2, Data1> d4(data2a, data1b);
         d4.execute();
        return 0;
    }
    Et le mieux de l'histoire, c'est que tout le boulot "qui prend du temps" sera effectué à la compilation

    Après, il y a d'autres choses sympa à faire comme mélanger le paradigme orienté objet et le paradigme générique, mais ca, c'est une autre histoire
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre habitué
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Points : 176
    Points
    176
    Par défaut
    Salut. J'ai développé ma librairie C++ pour du calcul haute performance en cosmologie et ma vision des choses c'est que l'orienté objet est à banir pour le coeur du calcul. Pour tout ce qui va autour ça peut aller (et encore), mais pour les endroits où ton programme va passer 80% de son temps, c'est clairement à éviter. Entre du virtuel dans tous les sens et de la métaprogrammation de haute volée tu peux gagner des facteurs entre 10 et 1000 (c'est arbitraire et ça dépend du problème mais c'est pour illustrer) en temps d'exécution et en empreinte mémoire. Bon la métaprog, au début c'est loin d'être une promenade de santé car la doc reste relativement rare et il faut pas mal expérimenter par soi-même. Après un certain temps, par contre, on trouve ça d'une élégance et d'une ingéniosité absolue et on ne jure plus que par ça (là encore c'est mon expérience personnelle de la chose). Pour ton problème, je te conseillerai de déjà te familiariser avec les concepts de SFINAE et de CRTP qui sont des choses à savoir quand on veut commencer à faire des choses sympas avec les types:
    http://en.wikipedia.org/wiki/Substit...s_not_an_error
    http://en.wikipedia.org/wiki/Curious...mplate_pattern

    Bonne chance

  4. #4
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2014
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Bonsoir,

    Un grand merci pour vos réponses + que précises ! Je sentais bien que le tuto sur les templates que je venais de parcourir avant-hier allaient m'être utiles (bon fais ch*** d'avoir passé une semaine dans des tutos sur la POO avec les virtual et des new/delete de partout, faire une lib de calcul, pour finalement découvrir que c'est mou du genou) .
    Je ne sais pas si je vais refondre toute ma lib de calcul car elle donne, malgré tout, des temps que je juge convenables ... bien que ça serait un exercice très formateur. Bien évidemment, je faisais pratiquement tout sous octave/matlab avant ; donc forcément ... le code compilé ça gaze en comparaison, même avec des virtual de partout comme j'aime (aimais) faire.

    En tous cas le concept de métaprogrammation me plait bien. Je crois que je m'y mettrai.

    Bonne soirée et encore merci.

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Note que l'énorme avantage de C++ est d'intégrer parfaitement les différents paradigmes que sont le procédural (les fonctions libres), l'orienté objet et le générique. Tu peux donc avoir certains aspects qui utilisent l'OO, d'autres le générique et meme certaines parties codée en procédural "pur" dans ton projet sans que cela ne te pose de problème, et tu peux parfaitement envisager (aussi) d'avoir une classe générique qui dérive d'une classe "normale" (ou l'inverse) dt qui fait appel à des fonctions libres.

    Tu dois donc utiliser le "meilleur des trois mondes" pour chaque aspect de ta bibliothèque/de ton application. Car le paradigme générique permet énormément de chose, et peut avoir des avantages dans certaines circonstances, mais peut malgré tout montrer ses limites dans d'autres, où l'orienté objet sera plus "logique d'utilisation" (l'inverse étant tout aussi vrai ).

    Ce qu'il faut retenir de tout cela, c'est que la première idée n'est pas forcément toujours la meilleure et qu'il est donc parfois intéressant "d'explorer d'autre horizons"
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre confirmé
    Profil pro
    Consultant en technologies
    Inscrit en
    Octobre 2013
    Messages
    158
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en technologies

    Informations forums :
    Inscription : Octobre 2013
    Messages : 158
    Points : 555
    Points
    555
    Par défaut
    Je suis assez d'accord avec ce qui est dit précédemment,
    mais une remarque d'importance suivant la taille de ton projet (et suivant son but) ,
    J'ai vu plus d'un thesard passé plus de temps à ré-écrire sa librairie car il a découvert un nouveaux truc cool, qui lui permettra d'avoir du code plus propre/rapide/sexy etc...
    En général le résultat c'est que le thesard il a pas le temps d'utiliser le code avant la fin de sa thèse. et bizarrement le jury (En tout cas pour les thèses en science non informatique), le style et la performance du code il s'en fout ce qu'il veut ce sont les résultats produits par le code.

    Tout ca pour dire, le temps CPU est moins cher que le temps développeur et faire un refactoring de masse à chaque fois que tu découvres un truc cool pour gagner des pouillemes de temps de calcul c'est pas forcément une bonne idée. (Bref sans refuser le changement, toujours y réfléchir à deux fois)

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    C'est tout l'intérêt de garder une version "qui fonctionne" sous la main (et donc des systèmes de gestion de versions concurrentes )

    Tu as tout à fait raison de le préciser, le refactoring de profondeur prend énormément de temps. Mais, parfois, une fois qu'on a quelque chose qui fonctionne bien, on apprécie d'avoir (ou on a besoin de) quelque chose qui fonctionne bien et rapidement.

    La première étape préconisée est toujours de commencer par optimiser au mieux les algorithmes les plus utilisés. La deuxième étape est généralement de recommencer la première, jusqu'à avoir la certitude que les algorithmes dans lesquels ont passe la majorité du temps soient le plus optimisés possible (une loi empirique dit qu'on passe 80% du temps dans 20% du code )

    Mais, si cela ne suffit toujours pas, certains choix techniques judicieux, comme le fait d'utiliser le paradigme générique pour certaines choses au lieu du paradigme oo, peuvent encore améliorer la situation. Au prix d'un temps de refactorisation parfois important . Parfois, cela vaut la peine de payer ce prix. Parfois, c'est un pari risqué, surtout si on est "pris par le temps"
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2014
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    J'ai vu plus d'un thesard passé plus de temps à ré-écrire sa librairie car il a découvert un nouveaux truc cool, qui lui permettra d'avoir du code plus propre/rapide/sexy etc...
    En général le résultat c'est que le thesard il a pas le temps d'utiliser le code avant la fin de sa thèse. et bizarrement le jury (En tout cas pour les thèses en science non informatique), le style et la performance du code il s'en fout ce qu'il veut ce sont les résultats produits par le code.
    Tu as très bien cerné mon cas Et je sais que tu as raison ...
    C'est effectivement l'un de mes travers (passer des temps inconsidérés sur des sujets annexes), mais c'est aussi ce qui m'a permis d'apprendre le C++, la POO, et de coder une lib performante (à comparer avec les langages interprétés bien entendu), de mettre un pied dans le monde de l'info finalement ; ainsi que d'autres compétences que je n'ai jamais apprises à l'école. Je suis bien conscient du fait que ce temps passé n'est pas rentabilisé ... pour la thèse du moins ... Acquérir un style de progra propre, optimisé et facilement partageable est une compétence valorisante pour de futurs projets à mon avis.
    A la louche, en supposant que j'aie acquis la progra générique C++ (ce qui n'est pas le cas encore), je pense qu'en 2 jours complets je pourrais recoder ma lib, elle n'est pas (encore) si grosse que cela. Ca serait l'occaz de mesurer le bénéfice de la vision générique sur mon application.
    Pour le moment, je me suis procuré cela :
    http://www.amazon.fr/Modern-Design-G...i+alexandrescu
    C'est une référence paraît-il (?)

    Merci à vous

  9. #9
    Membre averti

    Profil pro
    Étudiant
    Inscrit en
    Décembre 2004
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2004
    Messages : 499
    Points : 422
    Points
    422
    Par défaut
    tu as peur des appels virtuels à cause des perfs ? tu sais quel est le coût d'un appel virtuel ?
    parce qu'en temps normal le code de la méthode est déjà en cache, et le coût c'est juste une indirection pour la lecture de la VMT, VMT qui est déjà en cache, donc au final c'est rien du tout.

    sinon en faisant une dll et en utilisant final sur certaines classes et en exposant uniquement les méthodes qu'il faut ça devrait permettre au compilateur de faire du whole program optimization ?

  10. #10
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Citation Envoyé par abelb Voir le message
    Pour le moment, je me suis procuré cela :
    http://www.amazon.fr/Modern-Design-G...i+alexandrescu
    C'est une référence paraît-il (?)
    C’est un excellent livre. Par contre, il n’est pas à jour avec la dernière évolution du langage (C++11). Ça ne veut pas dire que ce qu’il dit est faux, mais parfois, certaines solutions ne sont pas présentées parce qu’elles n’existaient pas quand le livre a été écrit.

    Ça reste un très bon investissement.

  11. #11
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 704
    Points
    2 704
    Par défaut
    Citation Envoyé par _zzyx_ Voir le message
    J'ai vu plus d'un thesard passé plus de temps à ré-écrire sa librairie car il a découvert un nouveaux truc cool, qui lui permettra d'avoir du code plus propre/rapide/sexy etc...
    En général le résultat c'est que le thesard il a pas le temps d'utiliser le code avant la fin de sa thèse. et bizarrement le jury (En tout cas pour les thèses en science non informatique), le style et la performance du code il s'en fout ce qu'il veut ce sont les résultats produits par le code.
    D'un autre côté, j'ai dans mon parcours professionnel croisé pas mal de de thésards de physique qui faisaient des SSII parce qu'il n'y avait pas beaucoup de taf en physique. Alors acquérir de bonnes compétences en C++, ce n'est pas un mal.
    D'ailleurs, quand tu lis les contributions dans la mailing list de Boost, tu t'aperçois qu'il y a pas mal de physiciens.

    Là où je te rejoindrais, c'est que si on veut avoir du temps pour faire du beau code bien chiadé, il vaut mieux éviter le privé et travailler dans la recherche publique. Et donc réussir sa thèse...

Discussions similaires

  1. comment utiliser impdb dans mon cas ?
    Par TshAw dans le forum Import/Export
    Réponses: 1
    Dernier message: 30/01/2010, 09h46
  2. [PHP 5.2] Comment retinrer les accent dans mon cas
    Par pierrot10 dans le forum Langage
    Réponses: 1
    Dernier message: 15/06/2009, 16h56
  3. Comment utiliser les datasets dans mon cas
    Par dachir dans le forum ASP.NET
    Réponses: 5
    Dernier message: 13/01/2009, 10h44
  4. Comment aborder les collisions dans mon cas?
    Par MonsieurHelmut dans le forum Physique
    Réponses: 4
    Dernier message: 18/02/2007, 17h56
  5. [Débutant][JList] Comment ça marche dans mon cas ?
    Par gcore dans le forum Composants
    Réponses: 31
    Dernier message: 28/06/2004, 11h45

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