Aller au contenu

[C] [C++] Différences de performances entre C et C++ ?


jedifox

Messages recommandés

Bonsoir tout le monde,

Cette question me démange depuis longtemps. J'ai hésité à la mettre dans le forum dédié à Linux.

Donc, voilà.

GTK est, comme vous le savez sans doute, une bibliothèque permettant de créer des interfaces graphiques. On peut citer notamment The Gimp, ou encore, l'environnement de bureau Gnome. Cependant, cette bibliothèque est écrite en C et utilise une sorte de programmation orientée objet.

D'un autre côté, il y a Qt qui lui est aussi une bibliothèque graphique (voir même plus que ça) permettant de créer lui aussi des interfaces graphiques. On peut citer l'environnement de bureau KDE qui est en Qt. Mais, cette bibliothèque-ci est écrite en C++.

Alors, avec ces deux choses-là, qui sont tellement différentes mais qui utilisent la même méthode de programmation (notamment l'orienté objet), j'aimerais savoir s'il y a des réelles différences de performances à l'exécution.

Ensuite, est-ce une histoire de philosophie de préférer à utiliser du C que du C++ ?

Voilà. J'espère ne pas être trop confus et que vous puissiez me répondre :)

Merci beaucoup de votre aimable attention.

gholafox

Lien vers le commentaire
Partager sur d’autres sites

Vaste sujet que les différences de performances entre le C et le C++. Beaucoup d'articles ont été écrits sur le sujet. Ce serait difficile à résumer.

Ce serait interessant en effet de mesurer les perfs de deux implémentations de la meme application, une en Qt et l'autre sous GTK.

Si tu parles performances en terme de vitesse d'exécution (et non d'encombrement mémoire), ce n'est pas le choix C/C++ qui va faire une grosse différence, mais plutot ce que fait réellement la bibliothèque (exemple stupide un joli bouton est plus lourd à dessiner qu'un bouton moche) et comment elle le fait (l'algorythme de dessin du bouton).

Toutefois le C++ a apporté un tas de mots clefs qui permettent d'expliquer au compilateur ce que l'on veut faire (les inline, les methodes const et les references notamment) du coup ça lui permet d'optimiser certains aspects. Certains mots clefs sont maintenant supportés par des compilateurs C.

Le choix C / C++ n'est pas forcément si philosophique que ça. Ce sont deux langages différents. On choisit l'un des deux en fonction des critères habituels, comme :

- la disponibilité d'un compilateur sur la machine cible

- la maitrise personnelle du sujet

- la compatibilité avec un composant tierce

mais je doute fort que la vitesse entre en ligne de compte dans la plupart des cas.

De façon personnelle, je trouve que l'approche GTK de faire croire qu'on a un langage objet en utilisant des casts et des structures imbriquées les unes dans les autres est quand même horrible.

Lien vers le commentaire
Partager sur d’autres sites

Le C++ est plus lent que le C à cause des appels des constructeurs, des destructeurs et autres opérateurs implicites ou explicites. Mais cela permet en C++ de te garantir que tes objets sont bien initialisés, bien détruits, bien castés.

Ensuite la philosophie de préférer à utiliser du C que du C++: Le C, c'est du bas niveau. En C++ c'est de l'objet (pas pur) + des concepts (meta-progamming par exemple).

J'ai fait du GTK en 2005 et le truc marrant, c'est que pour gagner la différence de performances entre le C et le C++, les devs GTK ont préféré faire du C en simulant les objets avec des pointeurs de fonctions: :mdr:

Et si je ne me trompes pas, la philosophie entre le GTK et le Qt est différente:

  1. GTK est basée sur une table d'évènement, avec des événements prédéfinis pour chaque type (bouton, fenêtre, label, etc)
  2. Qt est basée sur un ensemble d'objets qui peuvent recevoir des événements et/ ou envoyer des événements: c'est vraiment très souple, mais il faut passer par un meta compilateur (le MOC).

Lien vers le commentaire
Partager sur d’autres sites

Le C++ est plus lent que le C à cause des appels des constructeurs, des destructeurs et autres opérateurs implicites ou explicites. Mais cela permet en C++ de te garantir que tes objets sont bien initialisés, bien détruits, bien castés.

Oui c'est plus lent en effet, mais tu payes ce que tu utilises. Si ta classe n'a pas de constructeur (ni aucune classe parente), il ne sera jamais appelé. C++ te promet juste (s'il ment il va en enfer) qu'il n'oubliera pas d'appeler un constructeur ou un destructeur. Au fond, que ce soit le compilateur qui génère un appel à MaClasse::MaClasse () ou bien que toi tu écrives explicitement InitMaStructure (&o);, je ne pense pas que la différence de perfs soit notable (ça peut meme etre plus rapide en C++ si le constructeur est inline).

Des que l'on definit des methodes virtuelles, les choses changent en effet, mais pour obtenir l'équivalent en C tu vas utiliser des choses qui sont a peu près aussi lentes. Et si tu fais ça naivement, ça m'étonnerait que tu atteignes les performances d'un code généré par un compilateur C++ récent.

Lien vers le commentaire
Partager sur d’autres sites

Oui c'est plus lent en effet, mais tu payes ce que tu utilises. Si ta classe n'a pas de constructeur (ni aucune classe parente), il ne sera jamais appelé.

:non: , il y a toujours un constructeur, un destructeur et un constructeur par recopie

C++ te promet juste (s'il ment il va en enfer) qu'il n'oubliera pas d'appeler un constructeur ou un destructeur.

Et les conversions :ouioui: . En C pur, les casts "réinterprètent" "le morceaux de mémoire". En C++, il va appeler des opérateurs de conversion implicite.

class Essai {
public:

operator int () {
	cout << "Operator Int" << endl;

	return 10;
}


operator float () {
	cout << "Operator Float" << endl;

	return 25.4f;
}
};


int main (void)
{

Essai essai;

int entier = essai;
float flottant = essai;

cout << "entier: " << entier << ", flottant: " << flottant << endl;

return 0;
}

Au fond, que ce soit le compilateur qui génère un appel à MaClasse::MaClasse () ou bien que toi tu écrives explicitement InitMaStructure (&o);,

La différence est essentiellement que l'être humain peut oublier de faire des choses, ou de les faire trop tôt/ tard :transpi:

je ne pense pas que la différence de perfs soit notable (ça peut meme etre plus rapide en C++ si le constructeur est inline).

Tout ne peut pas être inline. Et lorsque ta classe hérite, il y a une cascade des appels de la classe mère vers la classe fille.

Des que l'on definit des methodes virtuelles, les choses changent en effet, mais pour obtenir l'équivalent en C tu vas utiliser des choses qui sont a peu près aussi lentes. Et si tu fais ça naivement, ça m'étonnerait que tu atteignes les performances d'un code généré par un compilateur C++ récent.

Les méthodes virtuelles ont juste un déférencement en plus:

1) Sans virtuelle: objet->méthode(...)

2) Avec virtuelle: object->vtab[X](...)

Lien vers le commentaire
Partager sur d’autres sites

Oui c'est plus lent en effet, mais tu payes ce que tu utilises. Si ta classe n'a pas de constructeur (ni aucune classe parente), il ne sera jamais appelé.

:non: , il y a toujours un constructeur, un destructeur et un constructeur par recopie

Syntaxiquement oui, mais tu connais un compilateur digne de ce nom qui ne supprime pas un constructeur vide au moment de l'optimisation ? Perso j'en ai jamais vu.

EDIT: en fait je viens de verifier, le standard precise qu'un constructeur (copy ou pas) par defaut est INLINE, et l'expansion d'un constructeur inline vide doit pas peser grand chose.

Et les conversions :ouioui: . En C pur, les casts "réinterprètent" "le morceaux de mémoire". En C++, il va appeler des opérateurs de conversion implicite.

Encore une fois, tu ne payes que ce que tu utilises. Le C aussi genere des appels lors d'un cast (ftol notamment). Et de nombreux appels a memcopy lors de la copie d'une structure.

De tt facons, l'objet de mon post etait de dire que pour la plupart des projets, la difference entre le C et le C++ en terme de vitesse d'execution est tellement negligeable que ca devrait pas entrer en ligne de compte. Meme des projets de traitement video en temps reel sont ecrits en C++ (un specialiste d'OpenCV pour le confirmer ?).

Lien vers le commentaire
Partager sur d’autres sites

  • 2 semaines après...

Je confirme que la vitesse d'exécution entre le C et le C++ n'est pas très différente. La "surcharge" provoquée par l'utilisation du C++ est négligeable comparée à ce qu'il apporte en termes de fonctionnalités supplémentaires.

J'avais lu un article il y a quelques mois qui comparait sérieusement les deux langages et pour certains traitements, le C++ venait même devant le C. Il n'y avait aucune raison sérieuse de préférer l'un ou l'autre pour la vitesse.

Les systèmes d'exploitation utilisent beaucoup de C car il est simplement plus bas niveau. Et encore, en C++, on peut faire tout ce qui est possible de faire en C et inversement. C'est juste qu'il sera plus facile d'écrire certains types d'instructions en C ou en C++ selon le domaine d'application.

Un logiciel comptable ne sera pas programmé en C en 2011. Peut-être en C++ et encore, cela pourrait ne pas être le choix le plus judicieux...

Lien vers le commentaire
Partager sur d’autres sites

  • 4 semaines après...

C'est une question assez simple si on va dans l'absolu. La question est "est-ce que le plus rapide programme en C pour toute spécification demandée est plus, moins ou aussi rapide que le plus rapide programme en c++ pour la même spécification?"

Quoi qu'il arrive le C++ peut faire exactement ce que fait le C, car à à très peu de chose près (détails de forme) tout programme C est un programme C++, et le compilateur est capable de generer exactement le même binaire. Donc au sens strict C++ est au moins aussi rapide que le C.

Donc la question qui reste est : est ce que C++ est plus rapide que C? Pour cela il faudrait mettre en évidence quelque forme que le C++ serait capable de faire est que le C ne pourrait pas.

Historiquement il y avait les fonctions inline. Mais maintenant le C le supporte. donc match nul.

L'appel virtuel est plutôt un coût qu'un atout. Mais une programmation attentive permet en théorie d'éviter cet écueil, et les vtables sont implementable en c aussi bien qu'en c++ (et on peut faire mieux en c car un objet peut alors changer de classe). Mais de toute façon le C++ peut faire ce que fait le C.

Les exceptions C++ par contre apportent un mécanisme que le C ne peut égaler: la destruction des objets temporaires. Si cette fonction est necessaire dans la fonction demandée, il va faloir la gerer "à la main" en C (on exclut bien sur les tricheries sur la pile ou en assembleur), et cela va couter des ressources.

Donc la réponse est "il existe des spécification dont le plus rapide programme C++ est plus rapide que le plus rapide programme C"

Maintenant comparer gtk & qt/kde c'est une autre affaire.

Tout d'abord qt/kde n'est pas écrit en c++. Ils utilisent une espèce de précompilation appelée MOC qui ne relêve pas de la norme c++.

Mais le principal avantage de gtk est qu'étant écrit en C, il est aisement compatible avec tout autre langage tel que les langages de scripts.

Pour la rapidité de base de ces deux libs, je laisse d'autre répondre. ca dépend de tellement de choses (carte graphique... etc)

Lien vers le commentaire
Partager sur d’autres sites

Un logiciel comptable ne sera pas programmé en C en 2011. Peut-être en C++ et encore, cela pourrait ne pas être le choix le plus judicieux...

Le C++ est devenu, suite à la continuité de mauvais choix fait par ses normalisateurs, une monstruosité inmaintenable. Il n'est qu'a faire la liste exhaustive des différentes interprétations de l'expression

f();

l'on voit que le pauvre développeur confronté à un bug à cet endroit va devoir explorer une liste délirante de problemes potentiels.

A cause de cela le C++ est mort pour tout nouveau développement.

Pour ceux qui visent une durée de vie maximale, et ne pas se trouver en situation de devoir dire "ah ben ca je ne peux pas le faire, mais c'est de ma faute", il reste le C.

C'est pour cette raison que le kernel linux est en C (et certainement pas seulement "pour etre proche du matériel". Le C++ le permet autant)

Lien vers le commentaire
Partager sur d’autres sites

Le C++ est devenu, suite à la continuité de mauvais choix fait par ses normalisateurs, une monstruosité inmaintenable. Il n'est qu'a faire la liste exhaustive des différentes interprétations de l'expression

C'est pour cette raison que le kernel linux est en C (et certainement pas seulement "pour etre proche du matériel". Le C++ le permet autant)

Mouhaha ce troll!

Si il y a bien quelque chose que je reconnais a ce langage c'est sa complexité. De la a dire que ses concepteurs sont des abrutis et des bons a rien, permet moi de te dire que tu vas trop loin.

Il y très certainement des bêtises et des ambiguïtés dans la grammaire et la syntaxe de ce langage, mais comme dans tous les langages (a part ADA peut-être...).

Mais au fil du temps, tu finis par comprendre la logique et le pourquoi de ces "erreurs", qui n'en sont pas vraiment et qui logiquement ne devrait pas en être autrement.

La deuxième chose que je reconnais a ce langage, c'est l'amateurisme et l’incompétence de ses utilisateurs/programmeurs. Beaucoup trop de gens font du C++ comme il ferait du C, du Java ou du C#,

parce que çà "y ressemble presque". Erreur! Il ne faut pas confondre C et C++ et encore moins C++ a ces descendants. Je dois reconnaître que c'est un prétexte suffisant pour ne pas s'en servir.

Mais c'est aussi le langage le plus puissant et qui a ce jour offre le plus de possibilité, tout comme le C ou l'asm, mais tout en y apportant les outils et les moyens de faire du code portable, maintenable et générique.

Je ne connais pas de meilleurs langage pour faire des API et des bibliothèques (Qt/OpenCV/SFML/...) qui pourront ensuite être porte sur toutes autres types d'archis et de langages.

Si linux est écrit en C c'est pour plusieurs raisons, je ne les connais pas toutes. Mais très certainement car la "complexité" de C++ et de ce qu'il apporte n’était pas nécessaire, que la fiabilité des compilos a travers le

temps et les archis n’était(est?) pas satisfaisante, que Torvald ne comprend pas/n'aime pas/ne sait pas faire du C++... bref.

Pour recoller au topic, la différence de perf entre C et C++ est quasi nulle. Si C++ est plus rapide dans certains cas c'est grâce a certaines optimisations dues a l'apport de mots clefs et

de mécanismes du langage (const, références, RVO...).

Si il est plus lent, c'est qu'il fait/permet simplement plus de choses. A toi de voir si elles te sont utiles ou pas. Mais la différence est très rarement significatives (ex: les appels de méthodes).

Ce qui est sure, c'est que çà met 'achement plus temps a compiler!!!1

"Le C++ étant recompilé en C, je suis pas convaincu qu'il y ait une grand différence de performance."

Cela fait bien longtemps que ce n'est plus le cas sur les compilos les plus utilisés, GCC et VS. Sans parler de Clang++.

Lien vers le commentaire
Partager sur d’autres sites

@tatoute: En fait, je dirais plus (Dupond Style): Tout programme C++ est transformé en programme C. Pourquoi il ne faut pas mettre de tiret(s) avant le nom des variables? (<- Édit: Tipiak88)

L'autre truc qui me dérange:

1) Le C supporte les inline, mais c'est du C99. Bonne chance pour la compatibilité de ton programme après.

2) Je vois le C++ comme une immense trousse à outils: C/ Programmation Bas Niveau, Les références/ Alias, Objet, Programmation Générique + Calcul à la compilation, Late Binding + RTTI, Surcharge, Amitié, Héritage Multiple, Interfaces, Notion de Constante et peut être plus (Notions de statique, global,local par exemple). Ensuite c'est au développeur de choisir comment il va programmer. Mais jamais Le C++ ne se pliera au développeur.

Et c'est là le point le plus important. Le C++ n'est pas mort mais il n'a plus le vent en poupe. Et ceci pour une seule raison: les développeurs n'ont plus envie de se prendre la tête. Le Java, le C# ou le PHP tu apprends les types, les passages de paramètres et 2 3 trucs et c'est fini. Ils ont tous une immense librairie + quelques ajouts (tableaux associatifs, typage faible) et avec le compilateur ou la machine virtuelle tu fais un new et point barre.

En C++, tu dois apprendre le langage presque en entier, tu dois trouver une librairie qui va bien et ensuite faire de la programmation défensive (exceptions, smart pointeurs, etc).

Et même la STL est assez difficile à apprendre: Programmation Générique, Notion de trait de caractère, Notion de foncteur, etc.

:chinois:

Lien vers le commentaire
Partager sur d’autres sites

Mouhaha ce troll!

Si il y a bien quelque chose que je reconnais a ce langage c'est sa complexité. De la a dire que ses concepteurs sont des abrutis et des bons a rien, permet moi de te dire que tu vas trop loin.

Je maintiens. Je fais du C++ depuis 1989 et du C depuis 1985, et j'ai tres serieusement étudié le sujet des langages et de leur impact sur la maintenance. Je continue à gèrer et a maintenir des dev réalisés depuis 1990, quelque chose comme 2 milions de lignes. Je vois en direct les erreurs des choix des normalisateurs du C++. Et par aillleurs j'ai eu à échanger perso avec stroustrup (et d'autres). Ils ont jamais cessé de poursuivre la même stratégie délirante d'une complexification exponentielle, d'une modification ad naseaum des specs du langage pour coller à leur machin incompilable et inimplémentable appellé STL. Je peux pour chacun de leurs choix montrer qu'il existait des choix plus efficaces et simplificateurs.

D'autre part ils se sont permis de changer le sens des codes existants, Chacune des normes se trouvant en cotradiction avec la précédente.

Depuis 1 million d'années on devrait avoir de l'instrospection par exemple, ce qui aurait donné au C++ toute la puissance des ramasses miettes, et toute la force de la gestion de la mémoire "à la main", mais ils ont préférer se concentrer sur la signification ésotérique de l'interaction de l'operateur new avec les templates et les exceptions....

Des nuls, je le maintiens.

Lien vers le commentaire
Partager sur d’autres sites

Ce n'est pas l'introspection , mais la réflexion.

Et elle existe partiellement avec la RTTI mais aux dernières nouvelles tu flingues les performances.

Et c'est sûr si tu confonds le C avec le C99, les <iostream.h> avec les <iostream>, personne n'y peut rien pour toi.

Et il y a la librairie Boost qui est reconnue par un grand nombre de développeurs.

Et comme l'a dit Tipiak88 plus ou moins, le C++ n'a pas bougé depuis 1999: :fumer:

Lien vers le commentaire
Partager sur d’autres sites

Je maintiens. Je fais du C++ depuis 1989 et du C depuis 1985, et j'ai tres serieusement étudié le sujet des langages et de leur impact sur la maintenance. Je continue à gèrer et a maintenir des dev réalisés depuis 1990, quelque chose comme 2 milions de lignes. Je vois en direct les erreurs des choix des normalisateurs du C++. Et par aillleurs j'ai eu à échanger perso avec stroustrup (et d'autres). Ils ont jamais cessé de poursuivre la même stratégie délirante d'une complexification exponentielle, d'une modification ad naseaum des specs du langage pour coller à leur machin incompilable et inimplémentable appellé STL. Je peux pour chacun de leurs choix montrer qu'il existait des choix plus efficaces et simplificateurs.

D'autre part ils se sont permis de changer le sens des codes existants, Chacune des normes se trouvant en cotradiction avec la précédente.

Depuis 1 million d'années on devrait avoir de l'instrospection par exemple, ce qui aurait donné au C++ toute la puissance des ramasses miettes, et toute la force de la gestion de la mémoire "à la main", mais ils ont préférer se concentrer sur la signification ésotérique de l'interaction de l'operateur new avec les templates et les exceptions....

Des nuls, je le maintiens.

extraits de wikipedia et cplusplus.com:

"The first commercial implementation of C++ was released on October 14, 1985."

"In 1998, the C++ standards committee (the ISO/IEC JTC1/SC22/WG21 working group) standardized C++ and published the international standard ISO/IEC 14882:1998 (informally known as C++98).[8] For some years after the official release of the standard, the committee processed defect reports, and published a corrected version of the C++ standard, ISO/IEC 14882:2003, in 2003"

Ce qui laisse a penser que choisir de créer une appli de 2 millions de lignes en 1990 est un peu cavalier. Ou alors il ne faut pas s'étonner des changements et améliorations apportées. Il n'y a que approximativement 3 standards du langage, c++98, c++03 et un jour peut-etre c++0x. Je ne vois pas bien a quelles "normes" tu fais références car entre 98 et 03 très peu de choses changent.

Je ne crois pas que le but de Stroustrup et des membres du comité ait été de faire le langage le plus complique du monde (ou alors nous sommes tous victimes d'une machination mondiale orchestrée par quelques illumines du bocal). Leur plus grande erreur est a mon sens de s'etre base sur C, qui etait deja tres critiquable, et de n'avoir fait que rajouté des features de respectant la logique et la sémantique du C. C'est vrai qu'arrivé au bout du standard, ça peut paraître tordu (mais D nous sauvera tous, un jour...).

"Depuis 1 million d'années on devrait avoir de l'instrospection par exemple, ce qui aurait donné au C++ toute la puissance des ramasses miettes, et toute la force de la gestion de la mémoire "à la main", mais ils ont préférer se concentrer sur la signification ésotérique de l'interaction de l'operateur new avec les templates et les exceptions...."

Pour le coup la, je ne vois pas ou tu veux en venir...

Des exemples sur ta vision des erreurs du C++ et tes solutions m'interesse, par contre ;)

Lien vers le commentaire
Partager sur d’autres sites

Ce qui laisse a penser que choisir de créer une appli de 2 millions de lignes en 1990 est un peu cavalier. Ou alors il ne faut pas s'étonner des changements et améliorations apportées. Il n'y a que approximativement 3 standards du langage, c++98, c++03 et un jour peut-etre c++0x. Je ne vois pas bien a quelles "normes" tu fais références car entre 98 et 03 très peu de choses changent.

Non c'est simple: il faut regarder les librairies faites à l'époque, comme les MFC.

1) Il y avait un attribut caché "chaîne de caractères" pour stocker le nom de la classe, plus les "Getter" pour implémenter la méthode "IsKindOf"

2) Après la déclaration et l'implémentation des constructeurs et des destructeurs étaient cachées, afin de faire plus proprement le "Reference Counting" et l'allocation/ déallocation des objets.

C'étaient la joie des DECLARE_DYNAMIC/ DECLARE_DYNCREATE et IMPLEMENT_DYNAMIC/ DECLARE_DYNCREATE

Mais le RTTI à balayer tout cela mais est arrivé trop tard: "In the original C++ design, Stroustrup did not include run-time type information, because he thought this mechanism was frequently misused" (Wiki)

RTTI Quelques explications et aussi sur le wiki

De plus, de souvenirs, si les applications Microsoft plantaient assez souvent c'est à cause de cela: il avait mal conçu les MFCs. Depuis le C#/ .Net est arrivé.

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...