Enfin merci beaucoup Ehonn il faudra activer les optimisations![]()
Enfin merci beaucoup Ehonn il faudra activer les optimisations![]()
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.
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
Et sinon vu qu'on travaille en taille fixe, on peut aller chercher std::array dans C++11 ou Boost.
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
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
![]()
+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:
Voici un exemple catastrophique
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);
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); }
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; }
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.
Etant donné l'appel au constructeur par défaut *1000 avant, non.
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; }
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.
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.
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.
Salut,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
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
Code : Sélectionner tout - Visualiser dans une fenêtre à part std::vector<UnType> tab(ptr, ptr+size);![]()
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
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…
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.
Cela peut aussi coûter moins cher :
Want speed ? Pass by value
Partager