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++

  1. #21
    Membre à l'essai
    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
    Points : 17
    Points
    17
    Par défaut
    Enfin merci beaucoup Ehonn il faudra activer les optimisations

  2. #22
    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 mathro Voir le message
    J'ai trouvé que push_back est de complexité o(n^2) si on veux insérer n élement, c'est pour ça je l'ai pas utilisé.
    C'est faux. Insérer n éléments est en O(n).
    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.

  3. #23
    Membre habitué
    Profil pro
    Inscrit en
    Février 2008
    Messages
    114
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 114
    Points : 140
    Points
    140
    Par défaut
    Bonjour,

    Vis à vis des grosses différences de performance, et vu que tu sembles utiliser Visual Studio 2010, j'ai peut-être une idée du problème.

    Dans la configuration par défaut du mode Debug, il y a l'option "Basic Runtime Check" (dans les options de compilation C/C++ => Code Generation) qui semble ralentir énormément les objets de type class quand il n'est pas mis sur Default.

    J'ai remarqué ça quand j'ai fait un simple wrapper autour de l'API random du système (méthode Rand() qui appel la fonction rand() du système). En mode Release, les temps étaient sensiblement semblable, mais en Debug, ils étaient juste beaucoup trop éloignés.

    Sans l'option de compilation modifiée : API C : 16s, wrapper class : 25s
    Avec l'option de compilation modifiée : API C : 17s, wrapper class : 19s

  4. #24
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 156
    Points
    3 156
    Par défaut
    Et sinon vu qu'on travaille en taille fixe, on peut aller chercher std::array dans C++11 ou Boost.
    Find me on github

  5. #25
    Membre à l'essai
    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
    Points : 17
    Points
    17
    Par défaut
    Citation Envoyé par ketan Voir le message
    Dans la configuration par défaut du mode Debug, il y a l'option "Basic Runtime Check" (dans les options de compilation C/C++ => Code Generation) qui semble ralentir énormément les objets de type class quand il n'est pas mis sur Default.
    J'ai éxécuter une partie du code la ou le problème ce pose, sans changer cette option de compilation j'ai eu les résultats suivant
    Allocation dynamique: 14 s; class std::vector 97 s
    En changeant cette option
    Allocation dynamique: 14 s; class std::vector 52 s
    en activant de plus les optimisation (/O2; /Ot)
    Allocation dynamique: 13 s; class std::vector 30 s

  6. #26
    Membre à l'essai
    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
    Points : 17
    Points
    17
    Par défaut
    En faisant l'éxécution du programme en entier avec des données de taille moyenne (n=30) avec activation des optimisations (/O2, /Ot) mettre l'option 'Basic Runtime Checks' à 'Default' et l'option 'Debug Information format' à 'C7 compatible (/Z7)' car /ZI n'est pas compatible avec /O2, j'ai eu les résultats suivants:

    Allocation dynamique
    Debug:76s ; Release:33s
    std::Vector
    Debug:175s ; Release:32s

    Donc voilà, il faudra exécuter en mode Release ; reste à voir C++11

  7. #27
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Le "plus rapide" sera surement le reserve et push_back, puisque le resize fait de l'initialisation à une valeur par défaut via l'opérateur T().

    Maintenant, j'en pense qu'à ton niveau on n'en est pas à vouloir quelque chose qui tourne 0.0002ms plus vite mais tout simplement un script qui fonctionne..
    Avant de vouloir courir, on apprend à marcher.
    +1000

    Ceci aussi aide un peu à retirer des casseroles inutiles sous VS:
    _SECURE_SCL=0

    J'use et abuse de std::vector<> dans mes prg.
    Je n'ai jamais fait de resize() et n'ai jamais initialisé un vector à une taille donnée, la plupart du temps c'est inutile et contreproductif.
    Par contre les méthodes reserve() et capacity() sont utiles et importantes.

    Voici un exemple de bon usage:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    std::vector<int> v;
    v.reserve(1000);
    for (int i=0; i<1000; ++i)
     v.push_back(i);
    Voici un exemple catastrophique
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    std::vector<int> v;
    for (int i=0; i<1000; ++i)
    {
     v.reserve(v.capacity()+1);
     v.push_back(i);
    }

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

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

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Citation Envoyé par camboui Voir le message
    Je n'ai jamais fait de resize() et n'ai jamais initialisé un vector à une taille donnée, la plupart du temps c'est inutile et contreproductif.
    Dans le traitement d'image, tu connais la taille de l'image avant de déclarer ton vector donc tu peux l'initialiser directement à la bonne taille. Tu ne peux pas utiliser std::array (ou un tableau à la C) car cette taille n'est connu qu'à l'exécution (et que tu ne peux pas t'assurer que ton image tienne dans la pile). Utiliser reserve ici serait inutile et contre productif.

    Pour ton exemple, je pense que ceci est plus rapide si l'initialisation est plus rapide que le surcoût dû au push_back (même sans réallocation) (à tester) (mais c'est pas toujours possible j'en conviens).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    std::vector<int> v(1000);
    for (std::size_t i = 0; i < v.size(); ++i)
    {
        v[i] = i;
    }

  9. #29
    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
    Citation Envoyé par Ehonn Voir le message
    Dans le traitement d'image, tu connais la taille de l'image avant de déclarer ton vector donc tu peux l'initialiser directement à la bonne taille. Tu ne peux pas utiliser std::array (ou un tableau à la C) car cette taille n'est connu qu'à l'exécution (et que tu ne peux pas t'assurer que ton image tienne dans la pile). Utiliser reserve ici serait inutile et contre productif.
    Le traitement d'image ne fait pas exception.
    As-tu une quelconque utilité à initialiser les élément de ton vector à une valeur donnée ? Je n'en ai jamais eu besoin en faisait du traitement d'image.
    Le vector sert à stocker les pixels, on sait combien on veut en stocker, initialiser notre stockage par un pixel/une couleur par défaut à chaque emplacement/pixel ne sert à rien. On réserve la taille nécessaire, puis on lit/écrit/stocke chacun des pixels.

    Citation Envoyé par Ehonn Voir le message
    Pour ton exemple, je pense que ceci est plus rapide si l'initialisation est plus rapide que le surcoût dû au push_back (même sans réallocation) (à tester) (mais c'est pas toujours possible j'en conviens).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    std::vector<int> v(1000);
    for (std::size_t i = 0; i < v.size(); ++i)
    {
        v[i] = i;
    }
    Etant donné l'appel au constructeur par défaut *1000 avant, non.
    Le push_back ne coûte rien tant qu'il ne doit pas faire une réallocation.
    L'opérateur[] utilise le constructeur par copie, tout comme le push_back.
    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.

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

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

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Je trouve qu'il est plus simple (et plus court) d'utiliser la size du vector.

    push_back fait un if que operator[] ne fait pas, l'operator[] est donc potentiellement plus rapide.

  11. #31
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Le traitement d'image ne fait pas exception.
    As-tu une quelconque utilité à initialiser les élément de ton vector à une valeur donnée ? Je n'en ai jamais eu besoin en faisait du traitement d'image.
    Le vector sert à stocker les pixels, on sait combien on veut en stocker, initialiser notre stockage par un pixel/une couleur par défaut à chaque emplacement/pixel ne sert à rien. On réserve la taille nécessaire, puis on lit/écrit/stocke chacun des pixels.
    Il me semble qu'on est assez souvent amené à devoir utiliser des bibliothèques C, auquel cas on est obligé de faire un resize pour à la fois allouer la mémoire et dire au std::vector qu'il contient quelque chose. Même si l'initialisation des valeurs est effectivement inutile dans ce cas.

  12. #32
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,
    Citation Envoyé par Kalith Voir le message
    Il me semble qu'on est assez souvent amené à devoir utiliser des bibliothèques C, auquel cas on est obligé de faire un resize pour à la fois allouer la mémoire et dire au std::vector qu'il contient quelque chose. Même si l'initialisation des valeurs est effectivement inutile dans ce cas.
    Ben, j'ai presque envie de dire que, dans ce cas là, on disposer d'un constructeur particulièrement sympa...

    Au sortir d'une bibliothèque C, on aura sans doute soit un char * soit un void * (soit même un UnType * qui correspond à la structure C en question), mais on aura, aussi, une indication du nombre d'éléments que l'on doit s'attendre à y trouver.

    Une fois la conversion (si nécessaire) effectuée du char * ou en void * en un UnType*, tu devrait pouvoir utiliser le constructeur prenant les deux itérateurs, sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::vector<UnType> tab(ptr, ptr+size);
    Il me sembleque ce constructeur commence par calculer la taille requise (std::distance) et par faire un reserve avant de faire l'équivalent d'un grand memcpy global
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  13. #33
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    Citation Envoyé par mathro Voir le message
    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
    je pense qu'en parlant de retour par copie il parle de ce sujet
    http://stackoverflow.com/questions/1...nt-copy-values
    http://en.wikipedia.org/wiki/Return_value_optimization

    cela peut couter cher un retour par copie ou pas…
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  14. #34
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Ben, j'ai presque envie de dire que, dans ce cas là, on disposer d'un constructeur particulièrement sympa...
    Oui bien sûr, et il serait bête de s'en priver Mais j'ai déjà vu des cas (par exemple avec libpng) où la bibliothèque ne gère pas la mémoire elle même, et attend qu'on lui donne un pointeur vers une zone mémoire valide où elle pourra ranger les pixels.

  15. #35
    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
    Citation Envoyé par Kalith Voir le message
    Oui bien sûr, et il serait bête de s'en priver Mais j'ai déjà vu des cas (par exemple avec libpng) où la bibliothèque ne gère pas la mémoire elle même, et attend qu'on lui donne un pointeur vers une zone mémoire valide où elle pourra ranger les pixels.
    Perso dans ces cas-là, je préfère utiliser un simple C-Array, et si j'ai vraiment besoin d'un vector par la suite, je crée un vector avec après
    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.

  16. #36
    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
    Citation Envoyé par jabbounet Voir le message
    je pense qu'en parlant de retour par copie il parle de ce sujet
    http://stackoverflow.com/questions/1...nt-copy-values
    http://en.wikipedia.org/wiki/Return_value_optimization

    cela peut couter cher un retour par copie ou pas…
    Cela peut aussi coûter moins cher :
    Want speed ? Pass by value

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

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