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 :

Objet de transition / Optimisation de code


Sujet :

C++

  1. #1
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Points : 410
    Points
    410
    Par défaut Objet de transition / Optimisation de code
    Bonjour,

    J'aimerais vous soumettre le problème suivant :

    L'un des programmes que j'utilise lit des fichiers dans divers formats.

    Une première couche génère à partir de ces fichiers, des objets temporaires qu'il passe ensuite à une seconde couche qui les vérifie et instancie mon modèle de donnée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    fichier format A --> [Brique A] -\
    fichier format B --> [Brique B] ----> Objet intermédiaire ---> [traducteur] ---> Mon Modèle
    fichier format C --> [Brique C] -/
    L'intérêt de passer par cette couche intermédiaire réside dans le fait que les différents formats lus sont stables, alors que mon modèle est sujet à variations, je n'ai donc qu'une unique brique à modifier lorsque je change mon modèle.
    Les inconvénients sont nombreux, mais il n'en est pas question ici.

    Mon problème est d'optimiser l'une des briques qui lit les objets temporaire.
    Cette brique utilise un unique objet de chaque type, le remplit au fur et à mesure, avant de la passer à ma seconde couche.
    Elle le réinitialise ensuite, puis recommençe sa lecture.

    Pour le moment, la réinitialisation est faite atomiquement, c'est à dire qu'elle ressemble à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    MonObjetTemporaireDeTypeCapitaine::Reinit()
    {
    	m_iAgeDuCapitaine = -1;
    	m_fTailleDuCapitaine = -1.0F;
    	m_pFemmeDuCapitaine = NULL;
    	m_sNomDuCapitaine = "unamed";
    	...
    }
    Mais je me disais que je pourrais gagner du temps en créant un second objet temporaire avec mes valeurs par défaut avec ces valeurs et le copier à chaque fois pour réinitialiser l'autre (Je pense même qu'il s'agit d'un DP de création).

    L'idée étant que la copie d'un bloc de mémoire de n octets est plus rapide que la copie de n blocks de mémoire de 1 octet. Il faut donc que je veille à ce que mon constructeur par recopie utilise bien une copie d'un block.

    Je peux m'en sortir en faisant quelque chose comme ça :
    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
     
    struct SDonneeCopiablesDuCapitaine
    {
    	int m_iAgeDuCapitaine;
    	float m_fTailleDuCapitaine;
    	Individu* m_pFemmeDuCapitaine;
    };
    struct SDonneeNonCopiablesDuCapitaine
    {
    	std::string m_sNomDuCapitaine;
    };
    struct SDonneesDuCapitaine
    {
    	SDonneeCopiablesDuCapitaine dc;
    	SDonneeNonCopiablesDuCapitaine dnc;
    };
    struct SDonneesAlternativesDuCapitaine
    {
    	char dc[sizeof(SDonneeCopiablesDuCapitaine )];
    	SDonneeNonCopiablesDuCapitaine dnc;
    };
    class MonObjetTemporaireDeTypeCapitaine
    {
    	union
    	{
    		SDonneesDuCapitaine dc;
    		SDonneesAlternativesDuCapitaine dac;
    	}
    };
    ce qui me permettrait de construire mon constructeur par recopie comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    MonObjetTemporaireDeTypeCapitaine::MonObjetTemporaireDeTypeCapitaine(MonObjetTemporaireDeTypeCapitaine& toCopy)
    {
    	dac.dc = tocopy.dac.dc;		// ceci est une copie de tableau plus rapide qu'une somme de copies atomiques.
    	dac.dnc = tocopy.dac.dnc ;	// ceci est une suite de copies atomiques.
    }
    Cette façon de faire est un peu pénible car elle rend assez difficilement accessible mes données, et elle semble assez peu évolutive.

    Les questions que je me pose avant de commençer à réaliser cette optimisation sont :
    - Existe-t-il une façon plus élégante de gérer ce problème ?
    - Est-ce seulement intelligent de le faire (peut-être le compilateur le fait-il pour moi sans que je le sache) ?
    - Y a-t-il moyen d'automatiser la création des structures et des accesseurs en utilisant des template et des typelist. Le principal obstacle que je discerne étant, dans un typelist : comment reconnaitre un type copiable d'un type non-copiable ?

    Merci d'avoir lu.
    Merci à ceux qui répondront.

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Points : 473
    Points
    473
    Par défaut
    Est-ce un cas d'étude, ou as-tu un réél problème de performance ?
    Le DP auquel tu fais référence pourrait-être 'Prototype'.

    La plupart des compilateurs optimisent correctement la copy des PODs.
    Regrouper tes variables membres de type simple dans une structure permettra sûrement de les copier bit à bit. Il faudrait testé néanmoins, le gain de rapidité entre la copie successibe de chaque membre de type simple et celle d'une structure englobante.
    Ce que je ne comprends pas en revanche c'est l'interêt de regrouper les types 'complexes' dans une seconde structure.
    Attention néanmoins en subsituant l'appel d'une fonction de réinitialisation par celui d'un constructeur de copie. S'il y a allocation mémoire, il y aura nécessairement un surcoût à moins de passer par un 'placement new'.

  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
    Points : 4 625
    Points
    4 625
    Par défaut
    Normalement la réinitialisation ça se fait en créant un nouvel objet non ? Avec un swap éventuel.
    Boost ftw

  4. #4
    Membre expérimenté
    Avatar de Patriarch24
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    1 047
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 047
    Points : 1 640
    Points
    1 640
    Par défaut
    Mon problème est d'optimiser l'une des briques qui lit les objets temporaire.
    As-tu un réel problème de performances ? Plutôt que de réutiliser toujours le même objet pour la lecture, construits-en un nouveau. L'utilisation d'un prototype peut aussi être une bonne idée, mais cela suppose une construction par copie d'un objet.

    A l'arrivée, et à moins que tu ne sois à une instruction machine près, je te conseille de créer un objet à chaque fois.
    Ou alors, si tu tiens vraiment à réutiliser les objets consommés par la couche suivante, tu peux les gérer dans un pool en marquant l'objet consommé "dirty" quand il a été utilisé, et en ne le réinitialisant que quand c'est nécessaire, c'est-à-dire quand ta couche de lecture en réquisitionne un.
    En premier lieu, utilisez un moteur de recherche.
    En second lieu, postez sur le forum adéquat !

  5. #5
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Points : 410
    Points
    410
    Par défaut
    Tout d'abord, merci pour vos réponses.
    Citation Envoyé par Jan Rendek
    Est-ce un cas d'étude, ou as-tu un réél problème de performance ?
    Citation Envoyé par Patriarch24
    As-tu un réel problème de performances ?
    Oui, j'ai en effet des problèmes de performances, dans le sens ou je charge les fichiers moins vite que d'autres logiciels lisant les même données (mais chaque logiciel ne lit qu'un seul format).
    J'ai chronométré les différentes phases et l'amoindrissement des performances est en grande partie du au fait que j'utilise un modèle intermédiaire. Ceci dit, je ne peux pas m'en passer, j'essaie donc de raboter où je peux.
    Citation Envoyé par Jan Rendek
    La plupart des compilateurs optimisent correctement la copy des PODs.
    Regrouper tes variables membres de type simple dans une structure permettra sûrement de les copier bit à bit. Il faudrait testé néanmoins, le gain de rapidité entre la copie successibe de chaque membre de type simple et celle d'une structure englobante.
    Je vais faire ça, c'est un bon point de départ.
    Citation Envoyé par Jan Rendek
    Ce que je ne comprends pas en revanche c'est l'interêt de regrouper les types 'complexes' dans une seconde structure.
    Bonne question.
    Je suppose que ma structure SDonneesAlternativesDuCapitaine, n'a pas vraiment besoin de ces données-là, et donc ce n'est pas nécessaire de les factoriser.
    Bien vu.
    Citation Envoyé par Jan Rendek
    Attention néanmoins en subsituant l'appel d'une fonction de réinitialisation par celui d'un constructeur de copie. S'il y a allocation mémoire, il y aura nécessairement un surcoût à moins de passer par un 'placement new'.
    En effet, il serait plus malin de surcharger et d'utiliser l'opérateur d'assignation afin d'éviter de perdre du temps à instancier un nouvel objet.
    Citation Envoyé par Patriarch24
    Plutôt que de réutiliser toujours le même objet pour la lecture, construits-en un nouveau.
    Citation Envoyé par Patriarch24
    A l'arrivée, et à moins que tu ne sois à une instruction machine près, je te conseille de créer un objet à chaque fois.
    Là par contre, je ne vois pas ce que j'y gagne. Nouveau ou pas, mon objet devra être initialisé non ? Qui plus est je crois qu'il est plus rapide d'utiliser un objet de la pile qu'un objet du tas.
    Peux-tu être plus explicite sur le gain que j'aurais à cétruire l'ancien objet / créer un nouveau ?
    Citation Envoyé par Patriarch24
    Ou alors, si tu tiens vraiment à réutiliser les objets consommés par la couche suivante, tu peux les gérer dans un pool en marquant l'objet consommé "dirty" quand il a été utilisé, et en ne le réinitialisant que quand c'est nécessaire, c'est-à-dire quand ta couche de lecture en réquisitionne un.
    Hum ... de plus en plus flou.
    En réalisté, les opérations se déroulent séquentiellement :
    - la première couche remplit un objet intermédiaire
    - la seconde le traduit
    - la première couche re-remplit l'objet intermédiaire
    - la seconde le re-traduit
    - etc.
    Sauf que, les objets n'étant pas tous du même type, j'en ai un par type.
    Je ne sais pas si je suis clair.

    Quoi qu'il en soit, un gestionnaire d'objet et un flag dirty me semblent inutiles, puisqu'au moment où je remplis un objet intermédiaire, il est forcément déjà "dirty" sauf la première fois.

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

Discussions similaires

  1. [optimisation de code] mot clé this et objet = null
    Par Malatok dans le forum Général Java
    Réponses: 22
    Dernier message: 21/10/2011, 11h27
  2. Optimiser mon code ASP/HTML
    Par ahage4x4 dans le forum ASP
    Réponses: 7
    Dernier message: 30/05/2005, 10h29
  3. optimiser le code
    Par bibi2607 dans le forum ASP
    Réponses: 3
    Dernier message: 03/02/2005, 14h30
  4. syntaxe et optimisation de codes
    Par elitol dans le forum Langage SQL
    Réponses: 18
    Dernier message: 12/08/2004, 11h54
  5. optimisation du code et var globales
    Par tigrou2405 dans le forum ASP
    Réponses: 2
    Dernier message: 23/01/2004, 10h59

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