web-dev-qa-db-fra.com

Combien plus rapide est C++ que C #?

Ou est-ce maintenant l'inverse?

D'après ce que j'ai entendu, il y a des domaines dans lesquels C # s'avère plus rapide que C++, mais je n'ai jamais eu le courage de le tester par moi-même.

Je pensais que chacun de vous pourrait expliquer ces différences en détail ou m'indiquer le bon endroit pour obtenir des informations à ce sujet.

206
Trap

Il n’existe aucune raison stricte pour laquelle un langage basé sur des octets de code tel que C # ou Java doté d’un JIT ne soit pas aussi rapide que du code C++. Cependant, le code C++ était beaucoup plus rapide pendant longtemps et aujourd'hui encore dans de nombreux cas. Cela est principalement dû au fait que les optimisations JIT les plus avancées sont compliquées à implémenter, et que les très cool arrivent tout à l’heure.

Donc, C++ est plus rapide, dans de nombreux cas. Mais ce n'est qu'une partie de la réponse. Les cas où C++ est réellement plus rapide sont des programmes hautement optimisés, où des programmeurs experts ont parfaitement optimisé l’enfer du code. Cela prend non seulement beaucoup de temps (et donc coûte cher), mais entraîne généralement des erreurs dues à des suroptimisations.

D'autre part, le code dans les langages interprétés est plus rapide dans les versions ultérieures du runtime (.NET CLR ou Java VM), sans que vous ne fassiez rien. Et il existe de nombreuses optimisations utiles que les compilateurs JIT peuvent réaliser et qui sont tout simplement impossibles dans les langages avec pointeurs. En outre, certains soutiennent que la récupération de place doit généralement être aussi rapide ou rapide que la gestion manuelle de la mémoire, ce qui est souvent le cas. Vous pouvez généralement implémenter et réaliser tout cela en C++ ou C, mais cela sera beaucoup plus compliqué et sujet aux erreurs.

Comme l'a dit Donald Knuth, "l'optimisation prématurée est la racine de tout mal". Si vous savez vraiment avec certitude que votre application sera principalement composée d'arithmétique très critique en termes de performances, et que ce sera le goulot d'étranglement, et que cela va certainement être plus rapide en C++, et vous êtes sûr que C++ n'entrera pas en conflit avec vos autres exigences, allez pour C++. Dans tous les autres cas, concentrez-vous d'abord sur la mise en œuvre correcte de votre application dans la langue qui vous convient le mieux, puis recherchez les goulots d'étranglement des performances si elle fonctionne trop lentement, puis réfléchissez à la façon d'optimiser le code. Dans le pire des cas, vous aurez peut-être besoin d'appeler du code C via une interface de fonction étrangère. Vous aurez donc toujours la possibilité d'écrire des parties critiques dans un langage de niveau inférieur.

N'oubliez pas qu'il est relativement facile d'optimiser un programme correct, mais beaucoup plus difficile de corriger un programme optimisé.

Donner des pourcentages réels d'avantages en termes de vitesse est impossible, cela dépend en grande partie de votre code. Dans de nombreux cas, l’application du langage de programmation n’est même pas le goulot d’étranglement. Prenez les points de repère sur http://benchmarksgame.alioth.debian.org/ avec beaucoup de scepticisme, car ils testent en grande partie le code arithmétique, qui n’est probablement pas du tout similaire à votre code.

296
Martin Probst

C # peut ne pas être plus rapide, mais cela vous rend plus rapide. C'est la mesure la plus importante pour ce que je fais. :)

175
mattlant

C'est cinq oranges plus vite. Ou plutôt: il ne peut y avoir aucune réponse globale (correcte). C++ est un langage compilé statiquement (mais il existe également une optimisation guidée par profil), C # s'exécute avec l'aide d'un compilateur JIT. Il y a tellement de différences qu'il est impossible de répondre à des questions telles que «combien de temps», pas même en donnant des ordres de grandeur.

76
Konrad Rudolph

Je vais commencer par être en désaccord avec une partie de la réponse acceptée (et bien votée) à cette question en précisant:

Il y a beaucoup de raisons pour lesquelles le code JITted s'exécutera plus lentement qu'un programme C++ correctement optimisé (ou un autre langage sans surcharge d'exécution) Programme, notamment:

  • les cycles de calcul consacrés à l'exécution de code au moment de l'exécution sont par définition indisponibles pour une utilisation dans l'exécution du programme.

  • tous les chemins chauds dans JITter seront en concurrence avec votre code pour les instructions et le cache de données dans la CPU. Nous savons que le cache domine en termes de performances et que les langages natifs tels que C++ n’ont pas ce type de conflit, par définition.

  • le budget-temps d'un optimiseur d'exécution est nécessairement beaucoup beaucoup plus contraint que celui d'un optimiseur de compilation (comme l'a souligné un autre intervenant)

Résultat final: vous pourrez certainement créer une implémentation plus rapide en C++ qu'en C #.

Cela dit, combien de temps plus rapidement [] n'est pas quantifiable, car il y a trop de variables: tâche, domaine du problème, matériel, qualité des implémentations, etc. Vous aurez effectué des tests sur votre scénario pour déterminer la différence de performances, puis décider si cela en vaut la peine.

C’est un sujet très long et complexe, mais j’estime utile de mentionner que, par souci d’exhaustivité, l’optimiseur d’exécution de C # est excellent et qu’il est capable d’exécuter certaines optimisations dynamiques au moment de l’exécution qui ne sont tout simplement pas disponibles en C++ avec sa compilation ( statique) optimiseur. Même dans ce cas, l’avantage est toujours profondément présent dans la cour de l’application native, mais l’optimiseur dynamique est la raison du qualificatif "presque certainement" donné plus haut. 

-

En ce qui concerne la performance relative, les chiffres et les discussions que j’ai trouvées dans d’autres réponses me troublaient également; j’ai donc pensé que j’allais entrer dans les détails tout en corroborant les affirmations que j’ai faites plus haut.

Le gros problème avec ces tests de référence est qu’il est impossible d’écrire du code C++ comme si c’était écrit en C # et s’attendre à obtenir des résultats représentatifs (par exemple, effectuer des milliers d’allocations de mémoire en C++ va vous donner des chiffres épouvantables.)

Au lieu de cela, j’ai écrit un code C++ légèrement plus idiomatique et comparé au code C # fourni par @Wiory. Les deux principales modifications que j'ai apportées au code C++ sont les suivantes:

1) vecteur utilisé :: reserve ()

2) aplati le tableau 2d en 1d pour obtenir une meilleure localisation en cache (bloc contigu)

C # (.NET 4.6.1)

private static void TestArray()
{
    const int rows = 5000;
    const int columns = 9000;
    DateTime t1 = System.DateTime.Now;
    double[][] arr = new double[rows][];
    for (int i = 0; i < rows; i++)
        arr[i] = new double[columns];
    DateTime t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);

    t1 = System.DateTime.Now;
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < columns; j++)
            arr[i][j] = i;
    t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);
}

Temps d'exécution (libération): Init: 124 ms, Remplissage: 165 ms 

C++ 14 (Clang v3.8/C2)}

#include <iostream>
#include <vector>

auto TestSuite::ColMajorArray()
{
    constexpr size_t ROWS = 5000;
    constexpr size_t COLS = 9000;

    auto initStart = std::chrono::steady_clock::now();

    auto arr = std::vector<double>();
    arr.reserve(ROWS * COLS);

    auto initFinish = std::chrono::steady_clock::now();
    auto initTime = std::chrono::duration_cast<std::chrono::microseconds>(initFinish - initStart);

    auto fillStart = std::chrono::steady_clock::now();

    for(auto i = 0, r = 0; r < ROWS; ++r)
    {
        for (auto c = 0; c < COLS; ++c)
        {
            arr[i++] = static_cast<double>(r * c);
        }
    }

    auto fillFinish = std::chrono::steady_clock::now();
    auto fillTime = std::chrono::duration_cast<std::chrono::milliseconds>(fillFinish - fillStart);

    return std::make_pair(initTime, fillTime);
}

Temps d'exécution (libération): Init: 398µs (oui, c'est quelques microsecondes), Fill: 152ms

Total des temps d'exécution: C #: 289ms, C++ 152ms (environ 90% plus rapide)}

Observations

  • Changer l'implémentation C # pour la même implémentation de tableau 1d A donné Init: 40 ms, Remplissage: 171 ms, Total: 211 ms (C++ était encore presque 40% plus rapide).

  • Il est beaucoup plus difficile de concevoir et d'écrire du code "rapide" en C++ que d'écrire du code "normal" dans l'un ou l'autre langage.

  • Il est (peut-être) étonnamment facile d'obtenir de mauvaises performances en C++; nous avons vu cela avec des performances de vecteurs non réservées. Et il y a beaucoup de pièges comme celui-ci.

  • Les performances de C # sont plutôt étonnantes si l’on considère tout ce qui se passe au moment de l’exécution. Et cette performance est relativement facile d'accès

  • Plus de données anecdotiques comparant les performances de C++ et de C #: https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=gpp&lang2=csharpcore

L'essentiel est que C++ vous donne beaucoup plus de contrôle sur les performances. Voulez-vous utiliser un pointeur? Une référence? Empiler la mémoire? Tas? Polymorphisme dynamique ou élimine-t-il la surcharge d'exécution d'une table vt avec polymorphisme statique (via templates/CRTP)? En C++, vous devez ... euh, aller à faire tous ces choix (et davantage) vous-même, idéalement pour que votre solution résolve au mieux le problème que vous êtes en train de résoudre.

Demandez-vous si vous voulez réellement ou avez besoin de ce contrôle, car même pour l'exemple trivial ci-dessus, vous pouvez voir que même s'il y a une amélioration significative des performances, il faut un investissement plus important pour y accéder.

59
U007D

D'après mon expérience (et j'ai beaucoup travaillé avec les deux langages), le principal problème du C # par rapport au C++ est une consommation de mémoire importante, et je n'ai pas trouvé le moyen de le contrôler. C'était la consommation de mémoire qui allait éventuellement ralentir le logiciel .NET.

Un autre facteur est que le compilateur JIT ne peut pas se permettre trop de temps pour effectuer des optimisations avancées, car il s'exécute au moment de l'exécution, et l'utilisateur final le remarquera s'il prend trop de temps. D'autre part, un compilateur C++ dispose de tout le temps nécessaire pour effectuer des optimisations au moment de la compilation. Ce facteur est beaucoup moins important que la consommation de mémoire, à mon humble avis.

55
Nemanja Trifunovic

Un scénario particulier où C++ a toujours le dessus (et le restera pour les années à venir) se produit lorsque des décisions polymorphes peuvent être prédéterminées au moment de la compilation.

En règle générale, l'encapsulation et la prise de décision différée sont une bonne chose, car elles rendent le code plus dynamique, plus facile à adapter aux nouvelles exigences et à utiliser comme cadre. C'est pourquoi la programmation orientée objet en C # est très productive et peut être généralisée sous le terme de «généralisation». Malheureusement, ce type de généralisation a un coût au moment de l'exécution.

Généralement, ce coût n’est pas substantiel, mais il existe des applications où la surcharge des appels de méthodes virtuelles et de la création d’objets peut faire la différence (d’autant plus que les méthodes virtuelles empêchent d’autres optimisations telles que l’inclusion d’appel de méthodes). C++ présente un énorme avantage car vous pouvez utiliser des modèles pour réaliser un type de généralisation différent qui a un impact no sur l'exécution mais n'est pas nécessairement moins polymorphe que la POO. En fait, tous les mécanismes constituant OOP peuvent être modélisés à l'aide de techniques de modèle et de résolution au moment de la compilation.

Dans de tels cas (et certes, ils sont souvent limités à des domaines problématiques particuliers), le C++ gagne contre C # et des langages comparables.

32
Konrad Rudolph

C++ (ou C d'ailleurs) vous donne un contrôle fin de vos structures de données. Si vous voulez un peu tourner en rond, vous avez cette option. Les grandes applications Java ou .NET gérées (OWB, Visual Studio 2005 ) qui utilisent les structures de données internes des bibliothèques Java/.NET portent le bagage avec elles. J'ai vu des sessions de concepteur OWB utilisant plus de 400 Mo de RAM et BIDS pour un cube ou ETL design pénétrer également dans les centaines de MB.

Sur une charge de travail prévisible (telle que la plupart des tests de performance qui répètent un processus plusieurs fois), un JIT peut vous permettre d'obtenir un code suffisamment optimisé pour qu'il n'y ait aucune différence pratique.

OMI sur les grandes applications, la différence n'est pas tant le JIT que les structures de données que le code lui-même utilise. Lorsqu'une application nécessite beaucoup de mémoire, l'utilisation du cache est moins efficace. Les erreurs de cache sur les processeurs modernes sont assez coûteuses. Là où C ou C++ gagne vraiment, vous pouvez optimiser votre utilisation des structures de données afin de bien jouer avec le cache du processeur.

18

Pour les graphiques, la classe standard C # Graphics est beaucoup plus lente que GDI accessible via C/C++ . Je sais que cela n’a rien à voir avec le langage en soi, mais plutôt avec la plate-forme. est proposé au développeur en remplacement de GDI, et ses performances sont si mauvaises que je n'oserais même pas faire de graphiques avec.

Nous utilisons un repère simple pour déterminer la rapidité d'une bibliothèque graphique. Il s’agit simplement de tracer des lignes aléatoires dans une fenêtre. C++/GDI est toujours accrocheur avec 10000 lignes tandis que C #/Graphics a des difficultés à en faire 1000 en temps réel.

18
QBziZ

La récupération de place est la raison principale pour laquelle Java # NE PEUT PAS être utilisé pour les systèmes temps réel.

  1. Quand le GC aura-t-il lieu?

  2. Combien de temps cela prendra-t-il?

Ceci est non déterministe.

12
asdfgh

Nous avons dû déterminer si les performances de C # étaient comparables à celles de C++ et j'ai écrit quelques programmes de test pour cela (avec Visual Studio 2005 pour les deux langages). Il s'est avéré que sans nettoyage de la mémoire et en ne considérant que le langage (pas le framework), C # a fondamentalement les mêmes performances que C++. L'allocation de mémoire est bien plus rapide en C # qu'en C++ et C # a une légère influence déterministe lorsque la taille des données est augmentée au-delà des limites de la ligne de cache. Cependant, tout cela a finalement dû être payé et il y a un coût énorme sous la forme de résultats de performance non déterministes pour C # en raison de la récupération de place.

11
ILoveFortran

Comme d'habitude, cela dépend de l'application. Il y a des cas où C # est probablement trop lent, et d'autres cas où C++ est 5 ou 10 fois plus rapide, en particulier dans les cas où les opérations peuvent être facilement simulées.

9
Dark Shikari

Je sais que ce n’est pas ce que vous demandiez, mais C # est souvent plus rapide à écrire que C++, ce qui est un gros bonus dans un contexte commercial.

9
Kramii

C/C++ peut fonctionner considérablement mieux dans les programmes où il existe de grands tableaux ou une boucle/itération lourde sur des tableaux (de toute taille). C'est la raison pour laquelle les graphiques sont généralement beaucoup plus rapides en C/C++, car les opérations de tableau lourdes sous-tendent presque toutes les opérations graphiques. Il est notoire que .NET ralentit notablement les opérations d’indexation sur les tableaux en raison de toutes les vérifications de sécurité, et cela est particulièrement vrai pour les tableaux multidimensionnels (et, oui, les tableaux C # rectangulaires sont encore plus lents que les tableaux C # dentelés).

Les bonus de C/C++ sont plus prononcés si vous vous en tenez directement aux pointeurs et évitez Boost, std::vector et d’autres conteneurs de haut niveau, ainsi que inline de toutes les petites fonctions possibles. Utilisez les tableaux de la vieille école chaque fois que possible. Oui, vous aurez besoin de plus de lignes de code pour accomplir la même chose que vous avez fait en Java ou en C # en évitant les conteneurs de haut niveau. Si vous avez besoin d’un tableau de taille dynamique, il vous suffit de vous rappeler d’apparier votre new T[] avec une instruction delete[] correspondante (ou d’utiliser std::unique_ptr) - le prix de la vitesse supplémentaire est que vous devez coder avec plus de soin. Mais en échange, vous pouvez vous débarrasser des frais généraux liés à la mémoire gérée/au ramasse-miettes, qui peuvent facilement représenter 20% ou plus du temps d'exécution des programmes fortement orientés objet dans Java et .NET, ainsi que ceux gérés massivement. coûts d’indexation des tableaux de mémoire. Les applications C++ peuvent également bénéficier de certains commutateurs de compilation astucieux dans certains cas spécifiques.

Je suis un programmeur expert en C, C++, Java et C #. J'ai récemment eu la rare occasion d'implémenter exactement le même programme algorithmique dans les trois dernières langues. Le programme comportait de nombreuses opérations mathématiques et de tableaux multidimensionnels. Je l'ai fortement optimisé dans les 3 langues. Les résultats sont typiques de ce que je vois normalement dans les comparaisons moins rigoureuses: Java était environ 1,3 fois plus rapide que C # (la plupart des machines virtuelles sont plus optimisées que le CLR) et la version du pointeur brut C++ est environ 2,1 fois plus rapide que C #. Notez que le programme C # utilisait uniquement du code sécurisé. À mon avis, vous pourriez aussi bien le coder en C++ avant d'utiliser le mot clé unsafe.

Au cas où quelqu'un penserait que j'ai quelque chose contre C #, je terminerai en disant que C # est probablement ma langue préférée. C'est le langage de développement le plus logique, intuitif et rapide que j'ai rencontré jusqu'à présent. Je fais tout mon prototypage en C #. Le langage C # présente de nombreux petits avantages subtils par rapport à Java (oui, je sais que Microsoft a eu la chance de corriger bon nombre des faiblesses de Java en entrant dans le jeu tardivement et en le copiant sans doute). Faire un toast à la classe Calendar de Java? Si Microsoft consacre de réels efforts à l'optimisation du CLR et du .NET JITter, C # pourrait prendre le relais. Honnêtement, je suis étonné qu'ils ne l'aient pas encore fait: ils ont fait tellement de choses en langage C #, pourquoi ne pas poursuivre avec des optimisations de compilateurs percutantes? Peut-être si nous mendions tous.

7
Special Sauce

> D'après ce que j'ai entendu ...

Votre difficulté semble être de décider si ce que vous avez entendu est crédible, et cette difficulté ne fera que se répéter lorsque vous tenterez d'évaluer les réponses fournies sur ce site.

Comment allez-vous décider si ce que les gens disent ici est plus ou moins crédible que ce que vous avez entendu à l'origine?

Une solution consisterait à demander preuve.

Quand quelqu'un affirme "il y a des domaines dans lesquels C # s'avère plus rapide que C++" demandez-leur pourquoi ils disent cela, demandez-leur de vous montrer les mesures, demandez-leur de vous montrer des programmes. Parfois, ils auront simplement commis une erreur. Parfois, vous découvrez qu'ils expriment simplement une opinion plutôt que de partager quelque chose qu'ils peuvent montrer comme étant vrai.

Souvent, les informations et les opinions sont mêlées à ce que les gens prétendent, et vous devrez essayer de déterminer lequel est lequel. Par exemple, à partir des réponses dans ce forum:

  • "Prenez les repères sur http://shootout.alioth.debian.org/ Avec beaucoup de scepticisme, car Ceux-ci testent largement le code arithmétique, Qui est le plus probable pas semblable à votre code du tout. "

    Demandez-vous si vous comprenez vraiment ce que "ceux-ci testent en grande partie Code arithmétique" signifie, et ensuite Demandez-vous si l'auteur a réellement montré que sa demande est vrai.

  • "C’est un test plutôt inutile, car cela dépend vraiment de la manière dont Les programmes individuels ont été Optimisés; j’ai réussi à accélérer Certains d’entre eux de 4 à 6 fois ou plus, précisant que la comparaison entre programmes non optimisés est plutôt stupide. "

    Demandez-vous si l'auteur a Réellement démontré qu'il a réussi "accélérer certaines d'entre elles de 4 à 6 Fois ou plus" - c'est une prétention facile à faire!

6
Isaac Gouy

Les langages .NET peuvent être aussi rapides que le code C++, voire plus rapide, mais le code C++ aura un débit plus constant car le runtime .NET doit faire une pause pour GC , même s'il est très malin à propos de ses pauses.

Ainsi, si vous avez du code qui doit toujours être rapide sans interruption, .NET introduira la latence à un moment donné, même si vous êtes très prudent avec le GC d'exécution.

6
Florian Doyon

C'est une question extrêmement vague sans véritables réponses définitives.

Par exemple; Je préfère jouer à des jeux 3D créés en C++ qu'en C #, car les performances sont certainement bien meilleures. (Et je connais XNA, etc., mais cela ne s'approche pas vraiment de la réalité).

D'autre part, comme mentionné précédemment; vous devez développer un langage qui vous permet de faire ce que vous voulez rapidement, puis d’optimiser si nécessaire.

5
David The Man

Pour les problèmes parallèles embarrassants, lors de l'utilisation d'Intel TBB et d'OpenMP en C++, j'ai constaté une augmentation des performances d'environ 10 fois celle des problèmes similaires (calcul pur) en C # et TPL. SIMD est un domaine dans lequel C # ne peut pas concurrencer, mais j’ai aussi l’impression que TPL a des frais généraux considérables.

Cela dit, je n'utilise le C++ que pour les tâches critiques en termes de performances, car je sais que je serai capable de multithread et d'obtenir des résultats rapidement. Pour tout le reste, C # (et occasionnellement F #) convient parfaitement.

5
Dmitri Nesteruk

En théorie, pour les applications de type serveur exécutées depuis longtemps, un langage compilé par JIT peut devenir beaucoup plus rapide qu'un équivalent natif compilé. Comme le langage compilé JIT est généralement d'abord compilé dans un langage intermédiaire de bas niveau, vous pouvez néanmoins effectuer une grande partie des optimisations de haut niveau directement au moment de la compilation. Le gros avantage réside dans le fait que le JIT peut continuer à recompiler des sections de code à la volée au fur et à mesure qu'il reçoit de plus en plus de données sur la manière dont l'application est utilisée. Il peut organiser les chemins de code les plus courants pour permettre à la prédiction de branche de réussir aussi souvent que possible. Il peut réorganiser des blocs de code distincts qui sont souvent appelés ensemble pour les conserver tous les deux dans le cache. Il peut consacrer plus d’efforts à l’optimisation des boucles internes.

Je doute que cela soit fait par .NET ou l’un des JRE, mais c’était une question qui faisait l’objet d’une recherche lorsque j’étais à l’université. Il n’est donc pas déraisonnable de penser que ce genre de choses puisse bientôt se retrouver dans le monde réel .

4
Eclipse

J'ai testé vector en équivalents C++ et C # - List et tableaux 2D simples.

J'utilise les éditions Visual C #/C++ 2010 Express. Les deux projets sont de simples applications console, je les ai testés en version standard (sans paramètres personnalisés) et en mode débogage . Les listes C # fonctionnent plus rapidement sur mon ordinateur, l'initialisation de la matrice est également plus rapide en C #, les opérations mathématiques sont plus lentes.

J'utilise Intel Core2Duo [email protected], C # - .NET 4.0.

Je sais que l'implémentation de vecteurs est différente de la liste C #, mais je voulais simplement tester des collections que j'utiliserais pour stocker mes objets (et pouvoir utiliser un accesseur d'index).

Bien sûr, vous devez effacer la mémoire (disons pour chaque utilisation de new), mais je voulais garder le code simple.

Test de vecteur C++ :

static void TestVector()
{
    clock_t start,finish;
    start=clock();
    vector<vector<double>> myList=vector<vector<double>>();
    int i=0;
    for( i=0; i<500; i++)
    {
        myList.Push_back(vector<double>());
        for(int j=0;j<50000;j++)
            myList[i].Push_back(j+i);
    }
    finish=clock();
    cout<<(finish-start)<<endl;
    cout<<(double(finish - start)/CLOCKS_PER_SEC);
}

Test de liste C #:

private static void TestVector()
{

    DateTime t1 = System.DateTime.Now;
    List<List<double>> myList = new List<List<double>>();
    int i = 0;
    for (i = 0; i < 500; i++)
    {
        myList.Add(new List<double>());
        for (int j = 0; j < 50000; j++)
            myList[i].Add(j *i);
    }
    DateTime t2 = System.DateTime.Now;
    Console.WriteLine(t2 - t1);
}

C++ - tableau:

static void TestArray()
{
    cout << "Normal array test:" << endl;
    const int rows = 5000;
    const int columns = 9000;
    clock_t start, finish;

    start = clock();
    double** arr = new double*[rows];
    for (int i = 0; i < rows; i++)
        arr[i] = new double[columns];
    finish = clock();

    cout << (finish - start) << endl;

    start = clock();
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < columns; j++)
            arr[i][j] = i * j;
    finish = clock();

    cout << (finish - start) << endl;
}

C # - tableau:

private static void TestArray()
{
    const int rows = 5000;
    const int columns = 9000;
    DateTime t1 = System.DateTime.Now;
    double[][] arr = new double[rows][];
    for (int i = 0; i < rows; i++)
        arr[i] = new double[columns];
    DateTime t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);

    t1 = System.DateTime.Now;
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < columns; j++)
            arr[i][j] = i * j;
    t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);

}

Heure: (Release/Debug)

C++

  • 600/606 ms init matrice,
  • Remplissage de 200/270 ms,
  • 1sec/13sec vector init & fill.

(Oui, 13 secondes, j'ai toujours des problèmes avec les listes/vecteurs en mode débogage.)

C #:

  • 20/20 ms init matrice,
  • Remplissage de 403/440 ms,
  • 710/742 ms liste init & fill.
4
Wiory

Applications nécessitant un accès intensif à la mémoire, par exemple. Les manipulations d'images sont généralement mieux écrites dans un environnement non géré (C++) que géré (C #). Les boucles internes optimisées avec l'arithmétique de pointeur sont beaucoup plus faciles à contrôler en C++. En C #, vous devrez peut-être recourir à un code non sécurisé pour obtenir la même performance.

4
Kalle

En fait ça dépend. Si le code d'octet est traduit en code machine (et pas seulement JIT) (je veux dire si vous exécutez le programme) et si votre programme utilise plusieurs affectations/désallocations, cela pourrait être plus rapide car le GC algorithm nécessite juste une passe (théoriquement) dans la mémoire complète une fois, mais les appels normaux malloc/realloc/free en C/C++ entraînent une surcharge pour chaque appel (overhead d'appel, overhead de structure de données, cache cache;)).

C'est donc théoriquement possible (également pour d'autres langages GC).

Je ne vois pas vraiment l'inconvénient extrême de ne pas pouvoir utiliser métaprogrammation avec C # pour la plupart des applications, car la plupart des programmeurs ne l'utilisent pas de toute façon.

Un autre gros avantage est que le SQL, comme l’extension LINQ , offre au compilateur des possibilités d’optimisation des appels aux bases de données (en d’autres termes, le compilateur pourrait compiler l’ensemble du LINQ en un binaire "blob" où les fonctions appelées sont en ligne ou optimisées pour votre utilisation, mais je spécule ici).

3
Quonux

Si je ne me trompe pas, les modèles C # sont déterminés au moment de l'exécution. Cela doit être plus lent que les modèles de compilation de C++. 

Et quand vous prenez en compte toutes les autres optimisations au moment de la compilation mentionnées par tant d'autres, ainsi que le manque de sécurité qui signifie effectivement plus de vitesse ...

Je dirais que le C++ est le choix évident en termes de vitesse brute et de consommation de mémoire minimale. Mais cela se traduit également par plus de temps pour développer le code et vous assurer que vous ne perdez pas de mémoire ou ne causez pas d'exceptions de pointeur nul.

Verdict:

  • C #: Développement plus rapide, exécution plus lente

  • C++: développement lent, exécution plus rapide.

2
HumbleWebDev

Je suppose qu'il y a des applications écrites en C # qui fonctionnent rapidement, de même qu'il y a d'autres applications écrites en C++ qui s'exécutent rapidement (enfin, C++, juste un peu plus ancien ... et prenez aussi UNIX ...)
- la question est en effet - quelle est cette chose, les utilisateurs et les développeurs se plaignent ...
Eh bien, à mon humble avis, dans le cas de C #, nous avons une interface utilisateur très confortable, une hiérarchie très agréable de bibliothèques et un système d’interface complet de la CLI. Dans le cas de C++, nous avons des modèles, ATL, COM, MFC et Shebang complet de code déjà écrit et actif comme OpenGL, DirectX, etc. en une seconde - bang! c'est coincé).
Pour écrire du code en C # très simple et rapide (ne pas oublier que cela augmente également le risque d'erreur. Dans le cas de C++, les développeurs se plaignent de fuites de mémoire, - signifie "écrase" DLL hell "- problème avec les bibliothèques de support et de remplacement par les plus récentes ...
Je pense que plus vous maîtriserez le langage de programmation, plus votre logiciel sera caractérisé par sa qualité (et sa rapidité).

2
bgee

Je dirais ceci: les programmeurs qui écrivent du code plus rapide sont ceux qui sont le mieux informés de ce qui fait que les machines actuelles vont vite, et ce sont aussi ceux qui utilisent un outil approprié qui permet des calculs précis et déterministes techniques d'optimisation. Pour ces raisons, ces personnes utilisent C/C++ plutôt que C #. J'irais jusqu'à dire que c'est un fait.

2
Johan Boulé

> Après tout, les réponses doivent être quelque part, n'est-ce pas? :)

Umm, non.

Comme plusieurs réponses l'ont noté, la question est sous-spécifiée} de manière à inviter les questions à répondre, pas les réponses. Pour ne prendre qu'un seul chemin:

Et puis quels programmes? Quelle machine? Quel OS? Quel ensemble de données?

1
Isaac Gouy

Il existe des différences majeures entre C # et C++ en ce qui concerne les performances:

  • C # est basé sur GC/heap. L'allocation et le GC lui-même constituent un surcoût car la non-localité de l'accès mémoire
  • Les optimiseurs C++ sont devenus très bons au fil des ans. Les compilateurs JIT ne peuvent pas atteindre le même niveau car ils ont un temps de compilation limité et ne voient pas la portée globale

Outre que la compétence du programmeur joue également un rôle. J'ai vu un mauvais code C++ où les classes étaient passées par valeur comme argument partout. Vous pouvez réellement aggraver les choses en C++ si vous ne faites pas attention.

0
gast128

Cela dépend vraiment de ce que vous essayez d'accomplir dans votre code. J'ai entendu dire que c'est une légende urbaine qui dit qu'il y a une différence de performances entre VB.NET, C # et le C++ géré. Cependant, j'ai trouvé, au moins dans les comparaisons de chaînes, que le C++ pouvait battre le pantalon de C #, ce qui à son tour le bat de VB.NET.

Je n'ai nullement fait de comparaisons exhaustives de la complexité algorithmique entre les langages. J'utilise également les paramètres par défaut dans chacune des langues. Dans VB.NET, j'utilise des paramètres pour exiger la déclaration de variables, etc. Voici le code que j'utilise pour le C++ géré: (Comme vous pouvez le constater, ce code est assez simple). J'utilise la même chose dans les autres langues de Visual Studio 2013 avec .NET 4.6.2.

#include "stdafx.h"

using namespace System;
using namespace System::Diagnostics;

bool EqualMe(String^ first, String^ second)
{
    return first->Equals(second);
}
int main(array<String ^> ^args)
{
    Stopwatch^ sw = gcnew Stopwatch();
    sw->Start();
    for (int i = 0; i < 100000; i++)
    {
        EqualMe(L"one", L"two");
    }
    sw->Stop();
    Console::WriteLine(sw->ElapsedTicks);
    return 0;
}
0
Charles Owen