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 :

Eviter trop d'allocation dynamique


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut Eviter trop d'allocation dynamique
    Bonjour, afin de gagner en rapidité pour la création de petit objets, j'ai créé une petite classe (elle n'est que très très basique pour l'instant). Il me semble que boost propose une classe similaire. Cependant, ici le but est didactique.

    La voici :

    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    #include <iostream>
    #include <cstdlib>
     
     
    class Reservoir
    {
        private :
            void*pt;
            unsigned int size_pt;
            void* pt_pos;
        public :
            Reservoir()
            {
                pt=malloc(1*1000*1000);//1 MégaOctet par défaut. Valeur purement arbitraire
                size_pt=1*1000*1000;
                pt_pos=pt;
                if(pt==NULL)
                    std::cout<<"malloc_error";
            }
            Reservoir(unsigned int reserve)
            {
                pt=malloc(reserve);
                size_pt=reserve;
                pt_pos=pt;
                if(pt==NULL)
                    std::cout<<"malloc_error";
            }
            template<typename T, typename ...Args>
            T*make_new(Args...arg)
            {
                //Que mettre ?
                T*pt_tmp=(T*)pt_pos;
                (*pt_tmp)=T(arg...);//Très moche : on créé un objet temporaire pour rien.
                pt_pos+=sizeof(T);
                return pt_tmp;
            }
            ~Reservoir()
            {
                free(pt);
            }
     
    };
     
    using namespace std;
     
    int main()
    {
        Reservoir r;
        int*pt=r.make_new<int>(1);
        std::cout<<*pt;
        *pt=3;
        std::cout<<*pt;
        return 0;
    }
    Ce code utilise c++0x pour les constructeurs (template variadiques).
    Ce code ne gère pas (encore) le dépassement de la classe réservoir.
    Ce code est très imparfait.
    Mes questions :

    Y a t-il un moyen de faire quelque chose de plus propre ici :

    (*pt_tmp)=T(arg...);//Très moche : on créé un objet temporaire pour rien.

    ?

    Le compilateur saura-t-il optimiser la ligne de code ci-dessus ?

    Comment lors de la création de conteneurs (de la STL par exemple), dire au conteneur d'allouer les nouveaux éléments dans le réservoir ? Est-ce possible ?

    Le gain est-il important pour un vector de taille modifiable contenant env 10 000 000 int ?

  2. #2
    zul
    zul est déconnecté
    Membre chevronné Avatar de zul
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    498
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 498
    Par défaut
    Pour la première question, tu peux faire un "placement new", quelquehcose du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    T*pt_tmp=new (pt_pos) T(args...);
    Tous les containeurs de la STL peuvent être paramétrés par un Allocator donc oui c'est possible (il faut que ta classe réponde aux concepts de Allocator). Toutefois, je ne vois pas vraiment l'intérêt pour un vector dans ce cas (étant donné qu'il existe une méthode reserve() à std::vector et que les éléments d'un vecteur doivent être linéaire en mémoire)).

  3. #3
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    Pour la première question, tu peux faire un "placement new", quelquehcose du genre

    Code :


    T*pt_tmp=new (pt_pos) T(args...);
    Merci ! Sa marche très bien !
    Juste pour être sur, utiliser new de cette façon se contente d'appeler le constructeur mais n'alloue pas de mémoire ?


    Tous les containeurs de la STL peuvent être paramétrés par un Allocator donc oui c'est possible (il faut que ta classe réponde aux concepts de Allocator). Toutefois, je ne vois pas vraiment l'intérêt pour un vector dans ce cas (étant donné qu'il existe une méthode reserve() à std::vector et que les éléments d'un vecteur doivent être linéaire en mémoire)).
    Je connais la méthode reserve. L'objectif était avant tout didactique et utiliser ceci pour la STL permettrais à l'utilisateur de ne pas se s'embeter de faire des reserve (oui, je sais que ce n'est guère utile)...

  4. #4
    Membre Expert
    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
    Par défaut
    Juste pour être sur, utiliser new de cette façon se contente d'appeler le constructeur mais n'alloue pas de mémoire ?
    Oui, ça te permet de placer l'objet à un endroit précis de la mémoire. Par contre fait attention tu dois de ce fait appeler le dtor manuellement!

  5. #5
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    Par contre fait attention tu dois de ce fait appeler le dtor manuellement!
    J'avais complètement oublié cette partie là...
    Il faut donc que je stocke les positions de mes objets.
    Merci pour votre aide.

  6. #6
    Membre Expert

    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
    Par défaut
    Oui, le placement new standard ne fait que retourner l'addresse passée en paramètre, donc il n'y a qu'un appel au constructeur. A noter que dans ce cas il faut explicitement détruire l'objet (cf la FaQ).

    Pour les allocateurs de petits objet, tu peus voir du coté des SmallObject de loki (pour voir comment il fait), et au mieux acheter MC++D, il détail très bien le fonctionnement.

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

Discussions similaires

  1. Réponses: 15
    Dernier message: 06/12/2006, 16h03
  2. petit pbm allocation dynamique de stringGrid
    Par AnneOlga dans le forum C++Builder
    Réponses: 10
    Dernier message: 17/01/2004, 11h59
  3. Allocation dynamique de structures
    Par fr_knoxville dans le forum C
    Réponses: 8
    Dernier message: 06/05/2003, 21h59
  4. Allocation dynamique de mémoire en asm
    Par narmataru dans le forum Assembleur
    Réponses: 7
    Dernier message: 17/12/2002, 22h31
  5. Réponses: 4
    Dernier message: 03/12/2002, 16h47

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