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 :

perte de temps avec vector


Sujet :

C++

  1. #1
    Candidat au Club
    Homme Profil pro
    Ingénieur Capital Immatériel
    Inscrit en
    Juillet 2012
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur Capital Immatériel

    Informations forums :
    Inscription : Juillet 2012
    Messages : 2
    Points : 2
    Points
    2
    Par défaut perte de temps avec vector
    Bonsoir à tous !

    J'ai besoin d'aide, je suis en train de travailler sur un projet de matrices creuses de grandes tailles 200x200 notamment modifier une librairie existante pour l'optimisée. J'ai déjà effectué avec succès les opérations plus et inf pour des matrices représentées std::vector, mon problème est pour l'opération transpose, qui est très très lente par rapport à l'existant....

    voici le début de la classe matrixvector
    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
     
     
    struct Ttriplet
    {
     Ttriplet(int I, int J,serie S):i(I),j(J),s(S){}
    int i;
    int j;
    serie s;
            int geti(){return this->i;}
            int getj(){return this->j;}
            void seti(int k){i=k;}
            void setj(int k){this->j=k;}
            serie gets(){return this->s;}
            void sets(serie sa){this->s=sa;}
    } ;
     
    class matrixvector{
    private :
    		 int col,row;
    		 unsigned int size,capacity;
     
             std::vector<Ttriplet *> Data;
    ...
    et le code de la fonction transpose:
    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
     
    matrixvector transpose(matrixvector& a)
     {
        matrixvector result;
        //result.Data.reserve(a.size);
        Ttriplet *temp;
        int n=0,i=0,j=0;
        n=a.getsize();
        result.row=a.getcol();
        result.col=a.getrow();
         result.size=0;
        if(n>0)
        {
            result.size=1;
            for(i=0;i<a.col;++i)
            {
                for(j=0;j<n;++j)
                {
                  //  std::cout<<a.Data[j]->j<<std::endl;
                   if((a.Data.at(j)->j==i))
                        {
                            temp=new Ttriplet(a.getj(j),a.geti(j),a.Data[j]->s);
                            result.Data.push_back(temp);
                            result.size++;
                        }
    //
                }
     
            }
             return(result);
        }
     
          else
        {
            mem_limite  l(28);   throw(l);
        }
     
     }
    test:


    Merci !

  2. #2
    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 705
    Points
    2 705
    Par défaut
    Si tu te soucies des performances, commence par utiliser [] plutôt que at().

  3. #3
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    il est dommage d'avoir supprimer une des plus grandes sources d'optimisation de l'utilisation du std::vector : vector::reserve.
    Ton vector se remplit à coup de push_back... ce qui entraîne désallocation et réallocation en chaîne.
    L'utilisation de at est également à proscrire.

    Après dans les plus petites optimisations possibles
    - préfère la préincrémentation à la postincrémentation
    - éviter d'utiliser des variables temporaires, même pour ne stocker qu'un vecteur, tu peux faire un push_back(new T)
    - pourquoi stocker result.size et l'incrémenter à chaque push_back ? vector possède sa fonction size (en temps constant) ... qu'il suffit d'appeler à la fin
    - passer la matrix resultat en paramètre out plutôt que par return, ça évite une copie

    qu'est-ce que serie ? pourquoi ne pas le retourner en const& ?
    pourquoi il n'est pas en const& dans le paramètre de sets ?
    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.

  4. #4
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    bonjour geoberto et bienvenue sur le forum

    La programmation de libs numérique est un domaine complexe et à la vue de ton code, j'ai l'impression que tu débutes, non ?
    Je te conseille de regarder les libs existantes et voir comment ce type de problématique est résolue, tu apprendras beaucoup comme ça
    Par exemple (mais non exclusif) :
    boost.uBlas http://www.boost.org/doc/libs/1_50_0.../doc/index.htm
    nt2 http://nt2.lri.fr/contents.html

  5. #5
    Candidat au Club
    Homme Profil pro
    Ingénieur Capital Immatériel
    Inscrit en
    Juillet 2012
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur Capital Immatériel

    Informations forums :
    Inscription : Juillet 2012
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    Merci Bousk, mais c'est toujours aussi lent, la lenteur vient probablement du pushback...

    Le reserve ne change rien quel que soit la taille.

    Oui Guillaume je débute, j'ai déjà essayé avec un tableau de Ttriplet et j'ai passé une éternité à créer moi-même un pushback et à gérer les allocations dynamiques donc j'ai choisi d'utiliser les vector. Merci pour les libs je vais regarder ç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
    30
    31
    32
    33
    34
    35
     
    void transpose(matrixCOOvector& a, matrixCOOvector &b)
     {
        //matrixCOOvector result;
        b.Data.reserve(a.size);
        Ttriplet *temp;
        int i=0,j=0;
        b.row=a.getcol();
        b.col=a.getrow();
        if(a.size>0)
        {
            for(i=0;i<a.col;++i)
            {
                for(j=0;j<a.size;++j)
                {
                  //  std::cout<<a.Data[j]->j<<std::endl;
                   if((a.Data[j]->j==i))
                        {
                         //  temp=new Ttriplet(a.getj(j),a.geti(j),a.Data[j]->s);
                            b.Data.push_back(new Ttriplet(a.getj(j),a.geti(j),a.Data[j]->s));
     
                        }
    //
                }
     
            }
                    b.size=b.Data.size();
        }
     
          else
        {
            mem_limite  l(28);   throw(l);
        }
     
     }

  6. #6
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Pourquoi utiliser des pointeurs et de l'allocation dynamique ?
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  7. #7
    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 705
    Points
    2 705
    Par défaut
    Pour ce genre de problèmes, n'utilise pas des vecteurs, mais du stockage à l'ancienne à base de pointeurs. En plus de gagner en efficacité, tu pourras plus facilement extraire des colonnes.

    Et quand tu peux, alloue la mémoire en une seule fois.

  8. #8
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Je vois pas pourquoi utiliser un vecteur avec les valeurs au lieu des pointeurs , réservé à la taille finale, serait moins bien que faire ce que tu viens de dire?

  9. #9
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Parce que tu économiserais en pointeurs, appels de fonctions et autres?
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  10. #10
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Il y a une petite différence de performance entre l'opérateur [], un iterateur et un pointeur nu (double p = &t[0]. Certain diront non (que ça dépend entre autre des options de compilation)

    Ici, la différence entre vecteur et un tableau C-style est négligeable par rapport à tous les autres problèmes de conception, en particulier l'utilisation de push_back et l'absence de reserve. Il y a aussi le problème de new (faire 200*200 allocations ou presque, c'est pas top)

    Bref, comme d'hab -> profiling avant de chercher à faire de la micro-optimisation sur vector, un appel de fonction ou un déréférencement de pointeur

  11. #11
    Membre expert

    Avatar de germinolegrand
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2010
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Points : 3 892
    Points
    3 892
    Par défaut
    Bonjour, si tu sais à l'avance que tes matrices font 200x200, pourquoi utiliser un vector ?

  12. #12
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Parce que ce sont des matrices creuses (avec des trous donc -> ils n'y a pas 200*200 éléments)

  13. #13
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Pourquoi réserver une taille de a.size alors que la boucle se fait sur a.size*a.col ?
    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.

  14. #14
    Invité
    Invité(e)
    Par défaut
    Pourquoi réserver une taille de a.size alors que la boucle se fait sur a.size*a.col ?
    vraisemblablement a.getSize() retourne le nombre de triplets stockes dans matrixvector.Data

    cela dit, c'est assez byzarre de voir que tu crees une copie de ton instance plus transpose cette copie.
    Generalement quand tu transposes tu le fais sur la matrice de base.
    Sinon tu la copies.
    Mais la tu fais 2 en 1

  15. #15
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    Citation Envoyé par oodini Voir le message
    Pour ce genre de problèmes, n'utilise pas des vecteurs, mais du stockage à l'ancienne à base de pointeurs. En plus de gagner en efficacité, tu pourras plus facilement extraire des colonnes.

    Et quand tu peux, alloue la mémoire en une seule fois.
    On lit ca et on l’exécute, puis on arrête de dire des bêtises sur std::vector

  16. #16
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    bonjour geoberto et bienvenue sur le forum

    La programmation de libs numérique est un domaine complexe et à la vue de ton code, j'ai l'impression que tu débutes, non ?
    Je te conseille de regarder les libs existantes et voir comment ce type de problématique est résolue, tu apprendras beaucoup comme ça
    Par exemple (mais non exclusif) :
    boost.uBlas http://www.boost.org/doc/libs/1_50_0.../doc/index.htm
    nt2 http://nt2.lri.fr/contents.html
    Et ma préférée : Eigen http://eigen.tuxfamily.org/

  17. #17
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    Il y a une petite différence de performance entre l'opérateur [], un iterateur et un pointeur nu (double p = &t[0]. Certain diront non (que ça dépend entre autre des options de compilation)

    Ici, la différence entre vecteur et un tableau C-style est négligeable par rapport à tous les autres problèmes de conception, en particulier l'utilisation de push_back et l'absence de reserve. Il y a aussi le problème de new (faire 200*200 allocations ou presque, c'est pas top)

    Bref, comme d'hab -> profiling avant de chercher à faire de la micro-optimisation sur vector, un appel de fonction ou un déréférencement de pointeur
    Je réponds aux deux d'un coup. Sur Visual Studio, il me smeble que at() et [] font de la vérification. Pour at(), c'est obligatoire d'après la norme, mais pour [] ce n'est pas obligatoire de ne pas tester. Pour des raisons de sécurité, Microsoft a laissé le test.

  18. #18
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Ta dernière remarque a aiguisé ma curiosité, et voilà ce que Visual Studio (2010 ultimate) propose

    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
    const_reference at(size_type _Pos) const
    		{	// subscript nonmutable sequence with checking
    		if (size() <= _Pos)
    			_Xran();
    		return (*(this->_Myfirst + _Pos));
    		}
     
    const_reference operator[](size_type _Pos) const
    		{	// subscript nonmutable sequence
     #if _ITERATOR_DEBUG_LEVEL == 2
    		if (size() <= _Pos)
    			{	// report error
    			_DEBUG_ERROR("vector subscript out of range");
    			_SCL_SECURE_OUT_OF_RANGE;
    			}
     
     #elif _ITERATOR_DEBUG_LEVEL == 1
    		_SCL_SECURE_VALIDATE_RANGE(_Pos < size());
     #endif /* _ITERATOR_DEBUG_LEVEL */
     
    		return (*(this->_Myfirst + _Pos));
    		}
    Donc les check pour l'opérateur ne sont présents qu'en Debug.
    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.

  19. #19
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par Matthieu Brucher Voir le message
    Je réponds aux deux d'un coup. Sur Visual Studio, il me smeble que at() et [] font de la vérification. Pour at(), c'est obligatoire d'après la norme, mais pour [] ce n'est pas obligatoire de ne pas tester. Pour des raisons de sécurité, Microsoft a laissé le test.
    Il y a eu une version de visual studio où les vérifications étaient présentes même en mode optimisé avec les options par défaut (la motivation était qu'à l'époque windows se faisait attaquer sur sa stabilité, et donc que les gens prônant la sécurité même au détriment des performances ont eu le dessus). C'était une bêtise sans nom... Ils sont revenus en arrière. Si on travaille avec cette version (2005 et 2008), il est possible de désactiver ces vérifications en définissant la macro _SECURE_SCL à 0 (attention, il faut le faire partout, y compris dans les bibliothèques externes).

    Je pense que le main dev de la bibliothèque standard microsoft doit donner plus d'infos la dedans : http://channel9.msdn.com/Series/C9-L...ced-STL-3-of-n (je ne l'ai pas encore regardé, download en cours...)).
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  20. #20
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2008
    Messages : 87
    Points : 111
    Points
    111
    Par défaut
    attention même un profiler n'est pas suffisant, il dit où sont les passages qui prennent le plus de temps mais pas comment régler le problème.

    attention a la fragmentation mémoire et à l'ordre d'accès pour favoriser le cache. c'est toujours la mémoire le problème avec les grosses données.

    utiliser la carte graphique peut être une idée pour ce genre d'opérations mais 200x200 risque de ne pas être suffisant pour amortir les couts de setup + synchro.

Discussions similaires

  1. Perte de performance avec un Filtrage en temps réel
    Par Takumi dans le forum Windows Presentation Foundation
    Réponses: 10
    Dernier message: 15/10/2010, 22h37
  2. Pertes de mémoire avec Rave
    Par stepschn dans le forum Delphi
    Réponses: 8
    Dernier message: 15/10/2006, 11h18
  3. pb avec vectors de pointeurs
    Par e-teo dans le forum SL & STL
    Réponses: 5
    Dernier message: 27/07/2005, 14h11
  4. Installation et perte d'icône avec Firebird
    Par SebCBien dans le forum Applications et environnements graphiques
    Réponses: 22
    Dernier message: 31/10/2004, 16h46
  5. probleme avec vector
    Par venomelektro dans le forum SL & STL
    Réponses: 16
    Dernier message: 16/08/2004, 23h39

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