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 :

Optimisation en C++


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    F�vrier 2008
    Messages
    43
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : F�vrier 2008
    Messages : 43
    Par d�faut Optimisation en C++
    Bonjour � tous,
    utilisateur inconditionnel de Java, je me mets � C++ pour des probl�mes de rapidit� dex�cution. Seulement voil�, le m�me code en C++ tourne PLUS LENTEMENT (environ deux fois moins vite) que son petit fr�re en Java. Je sais bien que la JVM a fait beaucoup de progr�s, mais tout de m�me, je me dis que mon code C++ ne doit pas �tre optimal.
    Il s'agit d'ajouter dans une bo�te de simulation 1d (un intervalle r�el) des "particules" (des petits segments) de taille 1.0. La m�thode add(double x) ci-dessous tente de faire cela, et renvoie false si la particule que l'on tente d'ajouter recouvre d�j� une particule existante. J'ajoute que la bo�te est p�riodique.
    D�tails de programmation : la variable box est la taille de la bo�te, la variable spheres est le nombre de particules d�j� contenues dans cette bo�te. Les particules sont stock�es dans une list<double>, puisque j'ai cru comprendre que l'ajout d'un nouvel �l�ment � n'importe quel endroit de cette liste ne co�te pas cher.
    Voil�, voil�, il me reste � joindre le code, en esp�rant que vous trouverez une optimisation �vidente !!! Sinon, j'en resterai � Java...
    Merci par avance,
    S�bastien

    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
     
    bool Rsa1d::add(double x) {
    	if (center.size() == 0) {
    		center.push_back(x);
    		++spheres;
    		return true;
    	}
    	list<double>::iterator lower;
    	lower = lower_bound(center.begin(), center.end(), x);
    	double x1, x2;
    	if (lower == center.begin()) {
    		x1 = center.back() - box;
    		x2 = center.front();
    	} else if (lower == center.end()) {
    		x1 = center.back();
    		x2 = center.front() + box;
    	} else {
    		x2 = *lower;
    		--lower;
    		x1 = *lower;
    		++lower;
    	}
    	if ((fabs(x1-x) < 1.0)||(fabs(x2-x) < 1.0)) {
    		return false;
    	}
    	center.insert(lower, x);
    	++spheres;
    	return true;
    }

  2. #2
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    D�j�, la question b�te: Est-ce que l'optimisation est activ�e quand tu compiles ?

    PS: std::list<> correspond � java.util.LinkedList. Au niveau algorithme, je pense que c'est optimal...
    PPS:
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    F�vrier 2008
    Messages
    43
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : F�vrier 2008
    Messages : 43
    Par d�faut
    Je compile avec l'option -O2, j'esp�re que c'est suffisant (mais j'aurais tendance � croire que m�me sans, le programme C++ devrait �tre plus rapide que le programme Java).
    Je pense que la structure de donn�e est bien choisie, je me pose des questions quant � l'utilisation des it�rateurs dans mon code (je ne ma�trise pas bien les it�rateurs � la sauce C++), ainsi que l'algorithme lower_bound : j'ai lu la chose suivante sur www.cplusplus.com � propos de la complexit� :
    At most, logarithmic number of comparisons and linear number of steps in the length of [first,last). If used with random-access iterators, number of steps is reduced to logarithmic.
    Pour moi la complexit� devrait �tre logarithmique dans mon cas, non ?
    Merci,
    S

  4. #4
    Expert confirm�
    Avatar de Luc Hermitte
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2003
    Messages
    5 296
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : A�ronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 5 296
    Par d�faut
    lower_bound sur une liste (chain�e), ce n'est pas vraiment optimal ...
    Mieux vaut privil�gier les vecteur/deque si tu ne passe pas ton temps � faire des ajouts/retraits en milieu de tes collections. Avec des conteneurs de petites tailles, ils sont aussi acceptables en g�n�ral.

    Tu peux regarder les std::set aussi -- c'est aussi couteux que les listes en parcours it�ratif, mais en O(ln n) en extraction comme en insersion. Il te faudra fournir le foncteur qui va bien pour d�terminer une relation d'ordre entre tes sph�res.

    fabs ... c'est pour les float non ? (-> conversion). Prend std::abs(), le compilo se chargera ensuite d'utiliser la bonne fonction.

    PS: Et �dite ton message pour
    PPS: je me trompe ou spheres == center.size() ?
    PPPS: j'aurais bien conseiller de trier les entr�es pr�alablement, mais vu que l'algo a une m�moire, je sens que cela ne va pas le faire.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne r�ponds � aucune question technique par le biais de ce m�dia. Et de toutes fa�ons, ma BAL sur dvpz est pleine...

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    F�vrier 2008
    Messages
    43
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : F�vrier 2008
    Messages : 43
    Par d�faut
    Merci pour tous ces commentaires !!!

    Citation Envoy� par Luc Hermitte Voir le message
    lower_bound sur une liste (chain�e), ce n'est pas vraiment optimal ...
    Mieux vaut privil�gier les vecteur/deque si tu ne passe pas ton temps � faire des ajouts/retraits en milieu de tes collections. Avec des conteneurs de petites tailles, ils sont aussi acceptables en g�n�ral.
    Justement, j'ins�re � priori plut�t en milieu de liste...

    Citation Envoy� par Luc Hermitte Voir le message
    Tu peux regarder les std::set aussi -- c'est aussi couteux que les listes en parcours it�ratif, mais en O(ln n) en extraction comme en insersion. Il te faudra fournir le foncteur qui va bien pour d�terminer une relation d'ordre entre tes sph�res.
    Merci beaucoup ! Cela doit correspondre � ce que je cherche !

    Citation Envoy� par Luc Hermitte Voir le message
    fabs ... c'est pour les float non ? (-> conversion). Prend std::abs(), le compilo se chargera ensuite d'utiliser la bonne fonction.
    Ooops ! Des vieux restes du C... Je vais modifier mon code.

    Citation Envoy� par Luc Hermitte Voir le message
    PS: Et �dite ton message pour
    Done !

    Citation Envoy� par Luc Hermitte Voir le message
    PPS: je me trompe ou spheres == center.size() ?
    Correct, mais je me disais que j'allais limiter les appels (sans doute tr�s na�f ?).

    Citation Envoy� par Luc Hermitte Voir le message
    PPPS: j'aurais bien conseiller de trier les entr�es pr�alablement, mais vu que l'algo a une m�moire, je sens que cela ne va pas le faire.
    C'est inutile, car les sph�res sont ins�r�es une � une dans la liste au moyen de la seule m�thode add(double x) : la liste est donc constamment tri�e.

  6. #6
    Expert confirm�
    Avatar de Luc Hermitte
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2003
    Messages
    5 296
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : A�ronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 5 296
    Par d�faut
    Citation Envoy� par sbrisard Voir le message
    a- Justement, j'ins�re � priori plut�t en milieu de liste...

    b- C'est inutile, car les sph�res sont ins�r�es une � une dans la liste au moyen de la seule m�thode add(double x) : la liste est donc constamment tri�e.
    a- Sur une petite quantit� d'�l�ments, le vecteur pourra �tre plus efficace (quelques centaines -> d'o� le message de Lo�c)

    b- Ben, si tu n'avais pas eu ce filtrage bizarre � m�moire, un reserve sur le vecteur, suivi d'un remplissage, et conclu par un std::sort aurait �t� le plus efficace -> certitude de O(ln n), �limination du besoin en d�calage d'�l�ments pour remplacer cela par des �changes d'�l�ments.

    Citation Envoy� par ac_wingless
    Je pense qu'un conteneur tri� sera bien plus performant. Il est dommage que le conteneur tri� de base de la STL soit std::map, totalement surdimensionn� par rapport au besoin. On touche l� une des faiblesses du C++, � savoir une librairie standard squelettique compar� � Java ou C#.
    ??? Quoi ?
    Et std::set alors ?
    On touche aussi � sa richesse : des structures vraiment g�n�riques ...
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne r�ponds � aucune question technique par le biais de ce m�dia. Et de toutes fa�ons, ma BAL sur dvpz est pleine...

  7. #7
    Membre chevronn�

    Inscrit en
    Ao�t 2007
    Messages
    300
    D�tails du profil
    Informations forums :
    Inscription : Ao�t 2007
    Messages : 300
    Par d�faut
    Ah oui, j'ai �t� bien trop vite. J'ai fait ma crise cardiaque sur "_Distance(_First, _Last, _Count);" et j'ai pas d�taill� la suite. L'algorithme est effectivement lin�aire, et m�me pas plus lent en insertion en d�but de liste qu'en fin... et en plus, std::set convient tout � fait au probl�me. 3 gaffes en 2 posts, je me recouche, l�

  8. #8
    Membre chevronn�

    Inscrit en
    Ao�t 2007
    Messages
    300
    D�tails du profil
    Informations forums :
    Inscription : Ao�t 2007
    Messages : 300
    Par d�faut
    Il faut absolument retourner � Java!! C++ �ay le mal!
    S�rieusement, std::list n'�tant pas un conteneur tri�, la fonction ne peut qu'�tre lente. Ce n'est pas un probl�me d'algorithme, mais de conteneur. En effet, lower_bound ne peut pas vraiment profiter de sa dichotomie avec une liste chain�e, car chaque avancement d'indice va faire parcourir tous les noeuds interm�diaires (le pire cas �tant une insertion en d�but de liste, mais m�me le meilleur cas, � savoir une insertion exactement au milieu, d�pointera la moiti� des pointeurs de la liste!). En gros, sur une grosse liste, 99.999+% du temps sera pass� � d�pointer des pointeurs.
    Je pense qu'un conteneur tri� sera bien plus performant. Il est dommage que le conteneur tri� de base de la STL soit std::map, totalement surdimensionn� par rapport au besoin. On touche l� une des faiblesses du C++, � savoir une librairie standard squelettique compar� � Java ou C#.

  9. #9
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    En plus simple: lower_bound() ne peut pas �tre compl�tement logarithmique sur une liste cha�n�e, car l'acc�s al�atoire n'y est pas possible. Mais si j'ai bien compris l'extrait de doc, le nombre de comparaisons lui-m�me est quand m�me logarithmique.

    Pour ton code, il est possible qu'un std::set<> (java.util.TreeSet) soit plus performant, puisque l'insertion sera compl�tement logarithmique au lieu d'�tre plus-ou-moins lin�aire...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    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 : 51
    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
    Par d�faut
    Question : Combien as tu d'�l�ments dans ta liste ? 3, 10000, 100000000 ?

    Ensuite, sur une structure comme list o� on ne peut pas faire d'acc�s direct, mais uniquement case � case, l'algorithme lower_bound est lin�aire. Donc non optimal.

    Il me semblerait int�ressant de regarder avec une structure comme std::set, o� la recherche (fonction membre lower_bound, plut�t que l'algorithme) sera en log(n), et l'insertion guid�e par le r�sultat de la recherche sera en temps constant amorti.

    Edit : Grill� 4 fois le temps d'�crire ma r�ponse...
    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.

  11. #11
    Membre chevronn�

    Inscrit en
    Ao�t 2007
    Messages
    300
    D�tails du profil
    Informations forums :
    Inscription : Ao�t 2007
    Messages : 300
    Par d�faut
    Je viens de voir l'endroit d'o� la citation est tir�e... C'est grossi�rement faux. Pas votre faute, il faut bien faire confiance � des sites qui se pr�tendent didactiques... mais l�, vraiment pas de chance. En effet, contrairement � ce qui vous a �t� indiqu�, lower_bound est beaucoup beaucoup moins bien que lin�aire sur la taille de la liste. Exemple d'impl�mentation VS 2008:
    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
     
    template<class _FwdIt,
    	class _Ty,
    	class _Diff> inline
    	_FwdIt _Lower_bound(_FwdIt _First, _FwdIt _Last, const _Ty& _Val, _Diff *)
    	{	// find first element not before _Val, using operator<
    	_DEBUG_ORDER_SINGLE(_First, _Last, true);
    	_Diff _Count = 0;
    	_Distance(_First, _Last, _Count);
     
    	for (; 0 < _Count; )
    		{	// divide and conquer, find half that contains answer
    		_Diff _Count2 = _Count / 2;
    		_FwdIt _Mid = _First;
    		std::advance(_Mid, _Count2);
    		_DEBUG_ORDER_SINGLE(_Mid, _Last, false);
     
    		if (_DEBUG_LT(*_Mid, _Val))
    			_First = ++_Mid, _Count -= _Count2 + 1;
    		else
    			_Count = _Count2;
    		}
    	return (_First);
    	}
    Je n'ai pas souvenir d'avoir vu la moindre mention de comportement lin�aire sur d�placement pour lower_bound dans les listes, � part justement ce site, sur lequel je vais m'empresser de prof�rer des mal�dictions vaudou, au cas o� �a marcherait.

    On voit dans le code ci-dessus que c'est encore pire que ce que j'indique dans mon post ci-dessus: rien qu'avant de lancer la boucle de dichotomie, on d�pointe l'ensemble de la liste, juste pour obtenir la taille de recherche! Sur une liste un peu grande, 99.999% du temps pass� � d�pointer est probablement tr�s optimiste.

  12. #12
    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 : 51
    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
    Par d�faut
    L'algo que tu montres m'a tout l'air d'�tre lin�aire. Avec un mauvais coefficient devant, mais lin�aire tout de m�me.
    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.

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    F�vrier 2008
    Messages
    43
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : F�vrier 2008
    Messages : 43
    Par d�faut
    Merci � tous pour vos r�ponses !
    Je n'avais donc apparemment pas choisi la bonne structure de donn�es, et je vais basculer sur set � la place de list. J'aurais d� faire plus attention, puisque la structure correspondante que j'utilise en Java est TreeSet...
    Je vous tiendrai au courant des gains de temps qui en r�sultent.
    En tous cas, merci pour votre r�activit� !
    Vous �tes tous des

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    47
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 47
    Par d�faut
    Bonjour,

    En regardant ton code, j'ai quelques questions :
    1) La m�thode add semble maintenir la liste tri�e. Or, si tu envisages d'utiliser le set, c'est que cette notion t'importe peu... Vrai ?
    2) Peux-tu utiliser le type int � la place de double ?
    3) Ton conteneur vise � interdire l'utilisation de doublons. Vrai ?

    Si tu peux r�pondre par l'affirmative � ces trois hypoth�ses, alors tu peux impl�menter assez simplement un conteneur en te basant sur deux vecteurs (l'un contenant les �l�ments, l'autre la position, "l'adresse" des �l�ments dans le premier vecteur). Les �l�ments sont contigu�s dans le premier vecteur. L'ajout se fait toujours en fin, la suppression en milieu implique un petit swap. Dans les deux cas, il faut mettre � jour les "adresses".

    Tu obtiens alors un container permettant l'ajout, la suppression, le test de pr�sence, l'info sur le nombre d'�l�ments, en temps constant !

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Optimisation de votre SGBDR et de vos requ�tes...
    Par SQLpro dans le forum Langage SQL
    R�ponses: 35
    Dernier message: 11/01/2013, 11h49
  2. [langage] Optimiser la lecture d'un fichier
    Par And_the_problem_is dans le forum Langage
    R�ponses: 4
    Dernier message: 05/02/2003, 08h54
  3. [VB6] [BDD] Optimisation de l'accès aux données
    Par LadyArwen dans le forum VB 6 et ant�rieur
    R�ponses: 8
    Dernier message: 30/01/2003, 13h27
  4. [langage]Problème de temps de lecture, optimisation
    Par And_the_problem_is dans le forum Langage
    R�ponses: 2
    Dernier message: 08/01/2003, 08h47
  5. [langage] Optimiser la lecture d'un fichier
    Par And_the_problem_is dans le forum Langage
    R�ponses: 2
    Dernier message: 11/06/2002, 10h24

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