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 :

Utilisation de la class std::vector est très lourde!


Sujet :

SL & STL C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 38
    Par défaut Utilisation de la class std::vector est très lourde!
    Bonjour,
    J'ai écrit un code c++ ou j'utilise des fonction qui retournent et reçoivent des tableau uni et bidimentionnelle, j'ai utilisé pour cela les opérateur new et delete[] et là j'ai rencontré le pb de fuites de memoire que j'ai pas pu detecter ; alors j'ai fait recour à la class std::vector et là j'ai pas rencontrer le pb des fuites de mémoire mais le temps d'éxécution est augmenter d'une façon très considérable dans le premier cas j'ai eu 591000 millisecondes et dans le deuxième 6.214e+006 millisecondes, je vous donne un exemple d'une fonction qui reçoit une matrice 'a' et un tableau 'b' en paramètre et retourne la sous matrice de 'a' dont les colonnes sont spécéfié dans b.
    Utilisation de l'allocation dynamique:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    double * sous_matrice(double * a,int *b, int m, int e,int l)
    {
    	double *cl = new double[m * e];
    	int i,j;
    	for(i=0;i<m;i++)
    		for(j=0;j<e;j++)
    		{
    			cl[i*e+j]=a[i*l+b[j]];
    	}
    	return(cl);
    }
    Utilisation de la classe std::vector
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    typedef vector<double> Vec;
    typedef vector<int> VecInt;
    typedef vector<vector<double>> mat;
    mat sous_matrice(mat & a,VecInt & b, int m, int e,int l)
    {
    	mat cl(m,vector<double>(e));
    	int i,j;
    	for(i=0;i<m;i++)
    		for(j=0;j<e;j++)
    		{
    			cl[i][j]=a[i][b[j]];
    		}
    	return(cl);
    }
    Alors je sais pas est ce que le problème est dans l'utilisation de la class std::vector; ou l'allocation dynamique est meilleur que cette dernière dans le temps d'éxécution et là je doit detecter ou sont les fuites de mémoire???

  2. #2
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    Bonjour

    (message avant ton edit) 0. Utilise la balise [CODE] pour présenter du code

    (message avant ton edit, la fin est toujours valide) 1. Lorsqu'on on demande à comparer deux codes, on met ces deux codes dans des balises [CODE] différentes et on fait en sorte que chaque code ait un main() et qu'il compile (pour pouvoir reproduire le problème facilement).

    2. Lorsqu'on pose une question sur du temps d'exécution, on précise les options de compilation (utilises-tu bien -O3 ?)

    3. Quelle sont les tailles choisies ? Que vaut m et e ?

    4. C'est injuste, tu ne ne compares pas la même chose. Lorsque tu utilises le tableau "à la C", tu fais un accès linérisé; mais pas avec std::vector. Tu peux t'inspirer de la classe vector2D pour avoir un accès linérisé : lien vers le post avec la classe vector2D

    5. Si le compilateur ne fait pas d'optimisation, tu copies un std::vector qui est plus long que de copier un pointeur. Le compilateur devrait optimiser pour supprimer la copie. Pour être sur de ne pas faire de copie, on pourrait passer le std::vector en référence ou utiliser la move semantic de C++11.

    6. Pour le souci, des fuites mémoires :
    - il faut utiliser std::vector
    - pour les régler, tout new doit avoir son delete (et tout new [] doit avoir son delete []) il manque donc un delete [] cl; cl = nullptr; // cl = 0; si avant C++11 (la régle est celui qui alloue est celui qui détruit)

  3. #3
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 38
    Par défaut
    1-OK, en ce qui concerne les balise je vais en tenir compte prochainement, ce qui est de main(): ce que j'ai donné n'est qu'une fonction, le code est encore plus long et je fait appel à cette fonction dans d'autre fonctions. Comment j'ai comparer: J'ai deux projet dans le premier j'utilise l'allocation dynamique (new et delete[])et dans le deuxième la class std::vector. J'ai exacuter le premier puis le deuxième dans le meme laptop avec une instance de 30 objet et les temps d'exacution sont 591000 millisecondes et 6.214e+006 millisecondes respecivement. Dans le premier projet j'avait des fuites de mémoire et avec 40 objet le programme ne termine pas l'éxacution (break leak of memory) et le deuxième projet à pris 24 heur.
    2-Pour les options de compilation je comprend pas exactement ce que vous voulez dire par 'O3'
    3-m=3 et e varie de 10 jusqu'à 50 de meme pour l dans le premier projet et avec l=40 j'avait fuites de mémoire et le programme n'a pas pu continuer l'exacution
    4- je passe toujours la variable vector par référence, si le compilateur fait d'optimisation là je sais pas je vais chercher
    5- pour les fuites mémoire j'ai refait mon code avec la class std::vector -ce qui fait le projet 2- pour eviter les fuites de mémoire et là il ya pas ce pb mais l'éxécution est devenu très lente c'est pour cette raison que je vous ai écrit. pour le delete [] je l'utilise après chaque appelle de la fonction sous_matrice dans le premier projet (dans le deuxième c'est pas la peine parceque la deallocation ce fait automatiuqement) et j'ai toujours des fuite de mémoire.
    Ma question: est ce que le pb est dans la façon dans laquel j'ai utiliser la class std::vector??

  4. #4
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    Citation Envoyé par mathro Voir le message
    1-OK, en ce qui concerne les balise je vais en tenir compte prochainement, ce qui est de main(): ce que j'ai donné n'est qu'une fonction, le code est encore plus long et je fait appel à cette fonction dans d'autre fonctions.
    Bien et n'hésite pas à plus aérer ton texte avec la touche «Entrée».
    Tu peux faire un main articiel tel quel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int main()
    {
    	for (std::size_t nb_run = 0; nb_run <= 1000; ++nb_run)
    	{
    		for (std::size_t e = 10; e <= 50; ++e)
    		{
    			// Création de ta matrice
    			// Appel à ta fonction
    		}
    	}
     
    	return 0;
    }
    Citation Envoyé par mathro Voir le message
    2-Pour les options de compilation je comprend pas exactement ce que vous voulez dire par 'O3'
    L'option de compilation -O3 va demander au compilateur d'optimiser le programme au plus haut au niveau d'optimisation. Cette option est "indispensable" avant de vouloir optimiser un programme.
    GCC - Options That Control Optimization

    Citation Envoyé par mathro Voir le message
    4- je passe toujours la variable vector par référence, si le compilateur fait d'optimisation là je sais pas je vais chercher
    Je parle du return cl; de la fonction.

    Citation Envoyé par mathro Voir le message
    5- pour les fuites mémoire j'ai refait mon code avec la class std::vector -ce qui fait le projet 2- pour eviter les fuites de mémoire et là il ya pas ce pb mais l'éxécution est devenu très lente c'est pour cette raison que je vous ai écrit. pour le delete [] je l'utilise après chaque appelle de la fonction sous_matrice dans le premier projet (dans le deuxième c'est pas la peine parceque la deallocation ce fait automatiuqement) et j'ai toujours des fuite de mémoire.
    Tu as utiliser ma classe vector2D ?

    Citation Envoyé par mathro Voir le message
    Ma question: est ce que le pb est dans la façon dans laquel j'ai utiliser la class std::vector??
    Il faut compiler avec l'option -O3. Ensuite, il est préférable d'utiliser un vector linéarisé (comme dans ma classe vector2D). On peut aussi éviter la copie du return.

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    ton utilisation de vector n'est pas correcte et pas du tout semblable à tes tableaux.
    Pourquoi faire un vector de vector alors que tu n'utilises pas un tableau de tableau ?
    Les opérations de push_back sont les "plus lentes" s'il y a réallocation mémoire.

    Une bonne utilisation de vector utilisera un reserve préalable avant d'insérer les données.
    Une bonne pratique est aussi d'utiliser un vector unidimensionnel.

    En respectant ça, ce qui donne en plus un code semblable à ton code originel, tu obtiens
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    std::vector<double> sous_matrice(double * a,int *b, int m, int e,int l)
    {
    	std::vector<double> cl;
    	cl.reserve(m*e);
    	int i,j;
    	for(i=0;i<m;i++)
    		for(j=0;j<e;j++)
    		{
    			cl[i*e+j]=a[i*l+b[j]];
    	}
    	return(cl);
    }
    Puisque tu fais un retour par copie, il pourrait également être plus intéressant de passer le vector en paramètre out de la méthode à la place.

    pour les régler, tout new doit avoir son delete (et tout new [] doit avoir son delete []) il manque donc un delete [] cl; cl = nullptr; // cl = 0; si avant C++11 (la régle est celui qui alloue est celui qui détruit)
    La règle est uniquement qu'à tout new doit correspondre un delete. Il n'y a aucune obligation que celui qui réalise l'allocation doive faire la libération. Dieu merci, sinon on serait bien limité... Les problèmes de responsabilité ne se posent pas par hasard.
    Et libérer cl avant de le retourner c'est le meilleur moyen de faire une fonction qui ne réalise rien.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    Citation Envoyé par Bousk Voir le message
    La règle est uniquement qu'à tout new doit correspondre un delete. Il n'y a aucune obligation que celui qui réalise l'allocation doive faire la libération. Dieu merci, sinon on serait bien limité... Les problèmes de responsabilité ne se posent pas par hasard..
    Il s'agit d'une règle simplifiée, mettant en œuvre le RAII qui ne limite rien du tout (!). Cela permet d'avoir une gestion simple des ressources.

  7. #7
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 38
    Par défaut
    Ok. Déjà merci beaucoup pour vos réponses

    Je travail avec visual studio 2010 et j'arrive pas à trouver l'option de compilation o3, mais il ya d'autre façon d'optimiser la compilation, Je vais aller regarder ça de plus près et me creuser un peu la tête, en meme temps j'essayerai d'inclure votre class vector2D.je reviens vers vous une fois ça marche

  8. #8
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788

  9. #9
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 38
    Par défaut
    Bousk merci beaucoup pour votre réponse.
    En effet je suis entrain d'utiliser un tableau de tableau vous voyez bien que j'utilise dans le deuxième code Mais apparament votre code résout exactement mon problème: pas de fuites de mémoire d'une part et permet l'utilisation d'un tableau unidementionnelle ce qui permet d'optimiser le temps d'éxécution, c'est ce que j'ai besoin exactement. Merci infiniment
    Puisque tu fais un retour par copie, il pourrait également être plus intéressant de passer le vector en paramètre out de la méthode à la place.
    Je comprend pas exactement ce que vous voulez dire

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

Discussions similaires

  1. Pb std::vector dans une classe
    Par didi_di dans le forum Langage
    Réponses: 8
    Dernier message: 17/11/2009, 10h07
  2. Réponses: 10
    Dernier message: 30/06/2008, 19h59
  3. static std::<vector> c'est possible?
    Par Krishna dans le forum C++
    Réponses: 6
    Dernier message: 03/06/2008, 11h40
  4. 3 précisions sur l'utilisation des "std::vector"
    Par Invité dans le forum SL & STL
    Réponses: 9
    Dernier message: 10/01/2006, 00h42

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