comment vider un(e) deque rapidemment ?

comment vider un(e) deque rapidemment ? - C++ - Programmation

Marsh Posté le 17-11-2004 à 18:09:27    

Salut,
Voila mon pb, j'ai 2 classes A et B comme suit :

Code :
  1. class A{
  2. int a; int b; float c
  3. A(int un, int de, float f)
  4. {a=un; b=de; c=f;}
  5. ~A(){}
  6. };
  7. class B{
  8. deque<A*> lst;
  9. B(){}
  10. ~B(){
  11. for(deque<A*>::iterator itr=lst.begin();
  12.  itr!=direct_occ.end(); itr++)
  13. delete *itr;
  14. }
  15. };


Sauf erreur de recopie ca marche. Le(la) deque de la classe B est rempli dans differentes methodes que je n'ai pas ecrites.
 
Dans mon programme, j'efface au fur et a mesure les objets B dont je ne me sers plus, resultat c'est lent (~11s). Si au contraire je les conserve jusqu'a la fin (dans un vector) et qu'alors je les detruis, c'est rapide (~4s).
 
Si je remplace delete *itr par i++ dans le destructeur de B, alors je reviens a une execution rapide. (mais les objets A ne sont plus detruits !)
 
Que dois-je faire ? vider autrement mon(ma) deque ? revoir le destructeur de A ?
Merci pour toute info utile.
 
Pour infos je gere ~100 000 objets B contenant chacun entre 200 000 et 2 objets A. Et les objets B que je souhaite detruire sont parmi les plus gros.
 
KooK


Message édité par KooK le 17-11-2004 à 18:11:13
Reply

Marsh Posté le 17-11-2004 à 18:09:27   

Reply

Marsh Posté le 17-11-2004 à 20:32:39    

y a un lien entre B et A ?

Reply

Marsh Posté le 17-11-2004 à 23:29:04    

Taz a écrit :

y a un lien entre B et A ?


deque<A*> lst; dans la classe B
 
En fait, j'utilisais une file de pointeurs d'objet B que je vidais au fur et a mesure.
 
Je viens de me rendre compte que si je transfere dans un vecteur 'poubelle' les objets B dont je ne me sers plus et que je vide la poubelle de temps en temps, je gagne en temps d'execution.
 
Donc toujours meme interrogation, pourquoi est-ce plus lent d'effacer le contenu des pointeurs d'une deque (ou file) au fur et a mesure que de le transferer dans un vecteur qu'on efface de temps en temps ?
 
KooK


Message édité par KooK le 17-11-2004 à 23:29:21
Reply

Marsh Posté le 17-11-2004 à 23:37:42    

ais pourquoi t'as des pointeurs ?
 
 
non, c'est pas plus lent, le parcours d'une deque est un poil plus lent qu'un vector, mais ça devrait pas être critique. Ton appli est vraiment bizarre si ton point chaud, c'est la destruction ...
 
#     for(deque<A*>::iterator itr=lst.begin();
#         itr!=direct_occ.end();    itr++)
#     delete *itr;
 
super, mais fait gaffe de bien avoir un constructeur de recopie, affecation
et tu peux également n'appeler .end() qu'une seule fois.

Reply

Marsh Posté le 24-11-2004 à 19:39:32    

Il faut que je libere la memoire, sinon je sature vite l'ordi.
 
Je viens de refaire mon appli avec uniquement des listes (<list> ). La, je n'ai plus mon pb.
Est-ce que par hasard les deques seraient des tableaux "deguisees" en listes (la memoire n'est liberee qu'a la destruction de la deque) ?
Existe-t-il dans la STL une classe de liste simplement chainee ?
 
Et au cas ou ce n'etait pas clair, mes classes sont un peu plus etoffees que ce qui est ecrit, ce qui justifie l'utilisation des pointeurs ->il me semble qu'il est plus judicieux d'avoir une structure de 200 000 pointeurs que d'objets.
 
Merci quand meme de t'etre penche sur mon pb,
KooK

Reply

Marsh Posté le 24-11-2004 à 19:44:53    

heink ?
 
le truc auquel tu est peux être confronté, c'est que la deque est implémentée certainement comme une liste de tableau on va dire. Et donc ça risque de pas tout de suite tout désallouer quand tu réduis la taille. Ce que tu pourrais essayer de faire, deque<>::resize.
 
for_each ....
my_deque.resize(0);
 
Mais la list<>, c'est pire. Tu as un bien plus gros surcout en mémoire, le parcours est lent, et ça risque de fagmenter ta mémoire.
 
Tu devrais continuer à chercher du côté des deque<>.
sinon, tu peux toujours essayer
 
my_deque = deque<>()
 
voir carrément
my_deque.swap( deque<>() )

Reply

Marsh Posté le 24-11-2004 à 19:49:16    

mais attend, je capte pas, à la fin de ta classe B, ta deque membre, elle part à la poubelle ! il devrait y avoir aucun problème à ce moment là, quelque soit le conteneur, ça part à la trappe à la destruction de chaque B.
 
Tu veux pas essayer de faire un programme simple pour reproduire le problème ? tu utilises quoi comme compilateur ?
 
et tu mesures maintenant comment t'aurais moins souffert si t'avais réfléchi un peu et fais
 
template< template<typename T> class C >
class B
{
   typedef C<A*> Storage;
   Storgage lst;
};

Reply

Marsh Posté le 24-11-2004 à 19:55:38    

Citation :

Je viens de refaire mon appli avec uniquement des listes (<list> ). La, je n'ai plus mon pb.
Est-ce que par hasard les deques seraient des tableaux "deguisees" en listes (la memoire n'est liberee qu'a la destruction de la deque) ?
Existe-t-il dans la STL une classe de liste simplement chainee ?
 
Et au cas ou ce n'etait pas clair, mes classes sont un peu plus etoffees que ce qui est ecrit, ce qui justifie l'utilisation des pointeurs ->il me semble qu'il est plus judicieux d'avoir une structure de 200 000 pointeurs que d'objets.


Je ne vois pas en quoi ça impliquerait que la mémoire n'est libérée quà la destruction de la deque. Au contraire, il sufit de rediriger les pointeurs (itérateurs) sur les  éléments précédent et suivant, la suppression d'un élément ne fait pas perdre l'itérateur.
 
std::list est une liste simplement chaînée.
Quand à la structure de pointeurs sur les objets, avec les conteneurs standards, ça ne me paraît pas nécessaire.


Message édité par el muchacho le 24-11-2004 à 19:59:22
Reply

Marsh Posté le 24-11-2004 à 19:57:54    

non, pour la deque, en interne, c'est comme j'ai dit, une sort de liste de tableau.
 
et re-non pour std::list est doublement chainée

Reply

Marsh Posté le 24-11-2004 à 19:59:52    

el muchacho a écrit :

std::list est une liste simplement chaînée.


 
Cherche "std::list" dans google.fr, et prend le 3ème résultat  ;)  

Reply

Marsh Posté le 24-11-2004 à 19:59:52   

Reply

Marsh Posté le 24-11-2004 à 20:00:42    

J'ai viré le premier mais j'ai quand même faux sur le second  
Bon ben je crois que je vais m'écraser, là.:whistle:

Reply

Marsh Posté le 24-11-2004 à 20:02:08    

Lam's a écrit :

Cherche "std::list" dans google.fr, et prend le 3ème résultat  ;)

même pas besoin. Il doit savoir qu'une std::list peut se parcourir à reculons, sans double chainage, ça serait balaise :)

Reply

Marsh Posté le 24-11-2004 à 20:02:38    

'fectivement ;)

Reply

Marsh Posté le 24-11-2004 à 22:16:39    

Taz a écrit :

mais attend, je capte pas, à la fin de ta classe B, ta deque membre, elle part à la poubelle ! il devrait y avoir aucun problème à ce moment là, quelque soit le conteneur, ça part à la trappe à la destruction de chaque B.


Ca me rassure de ne pas etre le seul a ne pas comprendre.

Citation :

et tu mesures maintenant comment t'aurais moins souffert si t'avais réfléchi un peu et fais
 
template< template<typename T> class C >
class B
{
   typedef C<A*> Storage;
   Storgage lst;
};


Pas du tout, en quoi ca change/resoud le pb ?
Les conteneurs que j'utilise sont tous de la STL, tous ont un iterateur. Et j'utilise un typedef conteneur<A*>.
 
Je precise aussi que les 100 000 objets B que je gere sont dans une liste aussi (une deque au depart, quand c'etait lent).
 
KooK


Message édité par KooK le 24-11-2004 à 22:17:20
Reply

Marsh Posté le 24-11-2004 à 22:52:49    

Peut-être un élément de réponse là :
http://www.codeproject.com/vcpp/st [...] _deque.asp

Reply

Marsh Posté le 24-11-2004 à 22:54:21    

c'est quoi une 'deque' ?


---------------
Signatures aux choix Votez:  O - Le python c'est bon, mangez-en  O - L'abus de forum rend dependant, postez avec modération
Reply

Marsh Posté le 24-11-2004 à 22:56:23    

Phod a écrit :

c'est quoi une 'deque' ?


+1


---------------
Jubi Photos : Flickr - 500px
Reply

Marsh Posté le 24-11-2004 à 23:01:09    

double-ended queue, l'article que je donne dans le lien ci-dessus l'explique en détail

Reply

Marsh Posté le 24-11-2004 à 23:01:45    

ha voila, je serai moins ignoarant en me couchant ce soir :)
 
"Deque Overview :
The deque, like the vector, is also part of the Standard Template Library, the STL. The deque, or "double-ended queue", is very similar to the vector on the surface, and can act as a direct replacement in many implementations. Since it is assumed that the reader already knows how to effectively use the STL vector container, I have provided the table of deque member functions and operators below, solely for comparison and reference."


---------------
Signatures aux choix Votez:  O - Le python c'est bon, mangez-en  O - L'abus de forum rend dependant, postez avec modération
Reply

Marsh Posté le 24-11-2004 à 23:02:13    

grillé je suis
merci kan meme el muchacho


Message édité par Phod le 24-11-2004 à 23:02:26

---------------
Signatures aux choix Votez:  O - Le python c'est bon, mangez-en  O - L'abus de forum rend dependant, postez avec modération
Reply

Marsh Posté le 24-11-2004 à 23:58:27    

Ok, ce lien eclaire ma lanterne, merci beaucoup.
 
Dans mon cas, ce serait le temps de liberation (deallocation) de la deque qui serait (au moins en partie) responsable de mon pb.
 
Je considere mon probleme resolu.
Encore merci a "el muchacho" pour avoir trouve cet article et evidement merci a Nitron.
 
KooK :bounce:

Reply

Marsh Posté le 25-11-2004 à 00:03:47    

Kook > le truc c'est que si dès le départ, tu prends 5 minutes pour rendre ta classe template ET faire un typedef, changer la structure interne de ta classe se réduit à ne modifier qu'une seule ligne.
 
tu passerais de B<deque> à B<list> et hop, tout change

Reply

Marsh Posté le 25-11-2004 à 00:19:33    

KooK a écrit :

Ok, ce lien eclaire ma lanterne, merci beaucoup.
 
Dans mon cas, ce serait le temps de liberation (deallocation) de la deque qui serait (au moins en partie) responsable de mon pb.
 
Je considere mon probleme resolu.
Encore merci a "el muchacho" pour avoir trouve cet article et evidement merci a Nitron.
 
KooK :bounce:

ouais ben ça c'est pas normal. Pour une liste, ça revient à libérer N maillons. pour une deque N/M morceaux ... y a un truc de louche, tu ferais bien de l'éclaircir, tu ne pourras pas toujours changer à l'aveuglette de technique comme ça, surtout que la list risque sans doute de te pénaliser dans bien d'autres situations.
 
D'ailleurs est tu bien sur d'avoir remplacer strictement deque par list ?

Reply

Marsh Posté le 25-11-2004 à 00:22:01    

Dans mon cas, ca n'apporte rien de faire une classe template. Si je n'avais pas modifier le code pour gerer differement la liberation de la memoire (mon vecteur poubelle), changer le conteneur du typedef aurait ete suffisant comme je l'ai fait dernierement.
 
et oui, il n'y a plus de deque ... j'en suis sur grace au typedef :)
KooK


Message édité par KooK le 25-11-2004 à 00:24:12
Reply

Marsh Posté le 25-11-2004 à 00:26:54    

en attendant, ton explication ne me satisfait pas.  
 
Tu dis que ça te fait perdre du temps de libérer pas à pas, et que la deque mais trois plombes (d'ailleurs à quoi ? à être parcourue pour que tu fasses tes delete ? ou à se désallouée ?) et tu racontes que list est définitivement plus rapide, alors que ça implique une allocation pas à pas, et un parcours bien plus couteux ...

Reply

Marsh Posté le 25-11-2004 à 00:48:25    

Code :
  1. struct A
  2. {
  3.   char filler;
  4. };
  5. #include <boost/progress.hpp>
  6. template< template<typename> class C >
  7. void bench()
  8. {
  9.   typedef C<A*> Sequence;
  10.   typedef typename Sequence::iterator iterator;
  11.   const unsigned times = 5000000;
  12.   boost::progress_timer time_it;
  13.   Sequence seq;
  14.   for(unsigned i = 0; i < times; ++i)
  15.     {
  16.       seq.push_back( new A );
  17.     }
  18.   for(iterator i = seq.begin(), end = seq.end(); i != end; ++i)
  19.     {
  20.       delete *i;
  21.     }
  22. }
  23. #include <iostream>
  24. #include <vector>
  25. #include <list>
  26. #include <deque>
  27. #define TEST(X) do { \
  28. std::cout << #X << '\n'; \
  29. for(int i = 0; i < 3; ++i) { std::cout << '\t'; bench<X>(); } \
  30. } while(0)
  31. int main()
  32. {
  33.   TEST(std::list);
  34.   TEST(std::deque);
  35.   TEST(std::vector);
  36. }


 
à prendre avec des pincettes les chiffres mais on voit bien que list > deque > vector
 

std::list
        4.46 s
 
        3.31 s
 
        3.28 s
 
std::deque
        2.79 s
 
        2.80 s
 
        2.82 s
 
std::vector
        2.56 s
 
        2.54 s
 
        2.85 s


 
à vue d'oeil, le vector prenant 2x moins de mémoire que la list

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed