Question

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 tout le monde pourrait expliquer ces différences en détail ou me diriger vers le bon endroit pour obtenir des informations à ce sujet.

Était-ce utile?

La solution

Il n’existe aucune raison stricte pour laquelle un langage basé sur des octets de code tel que C # ou Java qui possède un JIT ne puisse pas être aussi rapide que du code C ++. Cependant, le code C ++ était beaucoup plus rapide pendant longtemps et aujourd'hui encore dans de nombreux cas. Ceci est principalement dû à la complexité de la mise en œuvre des optimisations JIT les plus avancées, et à l’optimisation de celles qui sont vraiment géniales.

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ù les programmeurs experts ont parfaitement optimisé l’enfer du code. Cela prend non seulement beaucoup de temps (et donc coûte cher), mais entraîne également souvent 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 plus 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 tous les maux". 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 la configuration requise, optez 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 de faire appel au 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é.

Il est impossible de donner un pourcentage d'avantages réels en termes de vitesse, 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 repères 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.

Autres conseils

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

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 que des questions telles que "Combien de temps faut-il" & # 8221; on ne peut y répondre, pas même en donnant des ordres de grandeur.

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 existe en réalité de nombreuses raisons pour lesquelles le code JITted s'exécutera plus lentement qu'un C ++ correctement optimisé (ou un autre langage sans surcharge d'exécution) programme , y compris:

  • Les cycles de calcul utilisés pour l'exécution du code JITting au moment de l'exécution ne sont par définition pas disponibles 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 plus contraint que celui d'un optimiseur au moment de la compilation (comme l'a souligné un autre intervenant)

Résultat final: à terme, vous serez certainement en mesure de créer une implémentation plus rapide en C ++ que vous ne le pourriez en C # .

Cela dit, la rapidité avec laquelle n'est pas quantifiable, car il y a trop de variables: tâche, domaine du problème, matériel, qualité des implémentations et de nombreux autres facteurs. 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 et la complexité supplémentaire.

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

-

En ce qui concerne les performances relatives, les chiffres et les discussions que j’ai trouvées dans d’autres réponses m'ont également perturbé. Je me suis dit que j’allais entrer dans le même temps et apporter un soutien aux déclarations que j’ai faites plus haut. .

Une grande partie du problème avec ces tests de performance est que vous ne pouvez pas écrire du code C ++ comme si vous écriviez du C # et que vous espériez obtenir des résultats représentatifs (par exemple, effectuer des milliers d’allocations de mémoire en C ++ va vous donner des chiffres terribles. )

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 modifications majeures 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 (validation): 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 (validation): Init: 398µs (oui, c'est quelques microsecondes), remplissage: 152 ms

Temps totaux d'exécution: C #: 289 ms, C ++ 152 ms (environ 90% plus rapide)

Observations

  • Changement de l'implémentation C # pour la même implémentation du tableau 1d cédé 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 "rapide". code en C ++ que ce qu’il faut pour écrire " regular " code dans l'une ou l'autre langue.

  • 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 à accès.

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

En résumé, 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 élimination de la surcharge d’exécution d’une vtable avec polymorphisme statique (via templates / CRTP)? En C ++, vous devez ... euh, arriver à faire tous ces choix (et davantage) vous-même, idéalement pour que votre solution résolve au mieux le problème que vous résolvez.

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

D'après mon expérience (et j'ai beaucoup travaillé avec les deux langages), le principal problème du C # comparé au C ++ est une consommation de mémoire importante, et je n'ai pas trouvé le moyen de le contrôler. C’est 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 ++ a 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.

Un scénario particulier dans lequel 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 ici un avantage considérable, car vous pouvez utiliser des modèles pour réaliser un type de généralisation différent qui n’a aucun d’impact sur l’exécution, mais qui n’est pas nécessairement moins polymorphe que la POO. En fait, tous les mécanismes constitutifs de la programmation orientée objet 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 il est vrai qu'ils sont souvent limités à des domaines problématiques particuliers), le C ++ gagne contre C # et des langages comparables.

C ++ (ou C d'ailleurs) vous donne un contrôle plus fin sur vos structures de données. Si vous voulez un peu tourner en rond, vous avez cette option. Applications Java ou .NET gérées de grande taille (OWB, Visual Studio & nbsp; 2005 ) qui utilisent le logiciel les structures de données internes des bibliothèques Java / .NET emportent le bagage avec elles. J'ai assisté à des sessions de concepteur OWB utilisant plus de 400 Mo de RAM et BIDS pour un cube ou ETL design pour entrer dans les centaines de MB également.

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 fournir un code suffisamment optimisé pour qu'il n'y ait aucune différence pratique.

IMO 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. C ou C ++ est réellement gagnant, car vous pouvez optimiser votre utilisation des structures de données afin de bien jouer avec le cache du processeur.

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 avec la plate-forme totale .NET, mais Graphics est ce qui est proposé au développeur en remplacement de GDI, et ses performances sont si mauvaises que je n'oserais même pas faire de graphisme. avec elle.

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 actif avec 10000 lignes tandis que C # / Graphics a des difficultés à en faire 1000 en temps réel.

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 classement général aura-t-il lieu?

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

Ceci n'est pas déterministe.

Nous avons dû déterminer si les performances de C # étaient comparables à celles de C ++ et j’ai écrit quelques programmes de test à cet effet (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 beaucoup plus rapide en C # qu'en C ++ et C # a un léger avantage en déterminisme lorsque la taille des données est augmentée au-delà des limites de la ligne de cache. Cependant, tout cela devait finalement ê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.

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.

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

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 est très lent dans les opérations d’indexation de tableau 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 chaque petite fonction possible. 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 suffira de vous rappeler d’apparier votre nouveau T [] avec une instruction delete [] correspondante (ou d’utiliser std: : unique_ptr ) - le prix pour la vitesse supplémentaire est que vous devez coder avec plus de soin. Mais en échange, vous devez vous débarrasser des frais généraux liés à la mémoire gérée / récupérateur de place, 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 3 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 le 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 le C #. . Notez que le programme C # utilisait uniquement du code sécurisé. À mon avis, vous pouvez également 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 Agenda 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 que si nous mendions tous.

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

Votre difficulté semble être de décider si ce que vous avez entendu est crédible. 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 les propos que les gens disent ici sont plus ou moins crédibles que ce que vous avez entendu à l'origine?

Une solution consisterait à demander des preuves .

Lorsqu'une personne déclare "il existe certains domaines dans lesquels C # s'avère plus rapide que C ++" demandez-leur pourquoi ils disent que , demandez-leur de vous montrer des 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 à ce forum:

  • " Prenez les points de repère sur http: //shootout.alioth.debian. org / avec beaucoup de scepticisme, comme ceux-ci testent largement le code arithmétique, qui est probablement pas semblable à votre code du tout. "

    Demandez-vous si vous avez vraiment comprendre ce que " ces testent en grande partie code arithmétique "" signifie, puis demandez-vous si l'auteur a effectivement vous a montré que sa demande est vrai.

  • "C'est un test plutôt inutile, car il dépend vraiment de la qualité les programmes individuels ont été optimisé; J'ai réussi à accélérer certains d'entre eux par 4-6 fois ou plus, en précisant que la comparaison entre les programmes non optimisés est plutôt stupide. "

    Demandez-vous si l'auteur a effectivement vous a montré qu'il a réussi pour "accélérer certains d'entre eux de 4 à 6 fois ou plus " - C'est une réclamation facile à faire!

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 moteur d'exécution .NET doit suspendre pendant GC , même s'il est très intelligent en ce qui concerne les pauses.

Ainsi, si vous avez du code à exécuter régulièrement et sans pause, .NET introduira la latence à un moment donné , même si vous êtes très prudent avec le GC d'exécution.

En ce qui concerne les problèmes parallèles embarrassants, lors de l'utilisation d'Intel TBB et d'OpenMP en C ++, j'ai constaté une augmentation de performances environ 10 fois supérieure à celle de 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 une surcharge considérable.

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

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

Par exemple; Je préférerais 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 n’approche pas vraiment de la réalité).

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

En théorie, pour les applications de type serveur de longue durée, un langage compilé par JIT peut devenir beaucoup plus rapide qu'un homologue compilé de manière native. 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 j’ai fait des recherches à l’époque lorsque j’étais à l’université. Il n’est donc pas déraisonnable de penser que ce genre de choses puisse se retrouver dans le monde réel à un point bientôt.

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 vous rapprocher des mêmes performances.

J'ai testé le vecteur dans les é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 tableau est également plus rapide en C #, les opérations mathématiques sont plus lentes.

J'utilise Intel Core2Duo P8600@2.4GHz, C # - .NET 4.0.

Je sais que l'implémentation des 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 l'indexeur).

Bien sûr, vous devez effacer la mémoire (disons pour chaque utilisation de nouveau ), 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: (version / débogage)

C ++

  • 600/606 ms init matrice,
  • remplissage du tableau 200/270 ms,
  • vecteur 1sec / 13sec init & amp; remplir.

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

C #:

  • 20/20 ms init init,
  • 403/440 ms de remplissage du tableau,
  • 710/742 ms liste init & amp; remplir.

Eh bien, ç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 allocations / désallocations, cela pourrait être plus rapide car L'algorithme GC n'a besoin que d'un seul passage (théorique) dans toute la mémoire, mais une transaction normale / realloc / free Les appels C / C ++ entraînent une surcharge pour chaque appel (surcharge de la communication, surcharge de la structure de données, erreurs de 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 les 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 code SQL, comme LINQ , fournit une extension. possibilités pour le compilateur d'optimiser les appels aux bases de données (en d'autres termes, le compilateur pourrait compiler le LINQ entier en un "binaire" blob où les fonctions appelées sont en ligne ou optimisées pour votre utilisation, mais je spécule ici).

Je suppose que certaines applications écrites en C # fonctionnent rapidement, de même qu'il existe d'autres applications écrites en C ++ qui s'exécutent rapidement (bien que C ++ est un peu plus ancien ... et prend également UNIX ...)
- la question est en effet - quelle est cette chose, les utilisateurs et les développeurs se plaignent de ...
Eh bien, à mon humble avis, dans le cas de C #, nous avons une interface utilisateur très confortable, une très belle hiérarchie de bibliothèques et un système d’interface complet pour la CLI. Dans le cas de C ++, nous avons des modèles, ATL, COM, MFC et tout un code déjà écrit, tel que OpenGL, DirectX, etc. dans une seconde - bang! c'est coincé).
Ecrire 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, ce qui signifie "écrase, appelle entre DLL", ainsi que "DLL enfer". - 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 la qualité (et la rapidité).

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

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

Heu, non.

Comme indiqué dans plusieurs réponses, la question est sous-spécifiée de manière à susciter des interrogations et non des réponses. Pour ne prendre qu'un seul chemin:

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

Si je ne me trompe pas, les modèles C # sont déterminés à 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 que vous ne provoquiez aucune exception de pointeur nul.

Verdict:

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

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

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 existe 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;
}

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

En outre, 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.

Inspiré par cela, j’ai fait un test rapide avec 60% des instructions communes nécessaires dans la plupart des programmes.

Voici le code C #:

for (int i=0; i<1000; i++)
{
    StreamReader str = new StreamReader("file.csv");
    StreamWriter stw = new StreamWriter("examp.csv");
    string strL = "";
    while((strL = str.ReadLine()) != null)
    {
        ArrayList al = new ArrayList();
        string[] strline = strL.Split(',');
        al.AddRange(strline);
        foreach(string str1 in strline)
        {
            stw.Write(str1 + ",");
        }
        stw.Write("\n");
    }
    str.Close();
    stw.Close();
}

Le tableau de chaînes et l'arraylist sont utilisés à dessein pour inclure ces instructions.

Voici le code c ++:

for (int i = 0; i<1000; i++)
{
    std::fstream file("file.csv", ios::in);
    if (!file.is_open())
    {
        std::cout << "File not found!\n";
        return 1;
    }

    ofstream myfile;
    myfile.open ("example.txt");
    std::string csvLine;

    while (std::getline(file, csvLine))
    {
        std::istringstream csvStream(csvLine);
        std::vector csvColumn;
        std::string csvElement;

        while( std::getline(csvStream, csvElement, ‘,’) )
        {
            csvColumn.push_back(csvElement);
        }

        for (std::vector::iterator j = csvColumn.begin(); j != csvColumn.end(); ++j)
        {
            myfile << *j << ", ";
        }

        csvColumn.clear();
        csvElement.clear();
        csvLine.clear();
        myfile << "\n";
    }
    myfile.close();
    file.close();
}

La taille du fichier d'entrée que j'ai utilisé était de 40 Ko.

Et voici le résultat -

  • Le code C ++ a été exécuté en 9 secondes.
  • code C #: 4 secondes !!!

Oh, mais c’était sous Linux ... avec C # sur Mono ... Et C ++ avec g ++.

OK, c’est ce que j’ai eu sous Windows & # 8211; Visual Studio & nbsp; 2003 & :

  • Le code C # a été exécuté en 9 secondes.
  • code C ++ & # 8211; horrible 370 secondes !!!
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top