Je suis une C++ et un développeur C#. J'ai développé des applications C# depuis la première version bêta de l' .NET framework et j'ai eu plus de 20 ans d'expérience dans le développement d'applications C++. Tout d'abord, le code C# ne sera JAMAIS plus vite qu'une application C++, mais je ne vais pas passer par une longue discussion sur le code managé, comment il fonctionne, l'inter-op de la couche, la gestion de la mémoire interne, le système de type dynamique et le garbage collector. Néanmoins, permettez-moi de continuer en disant que le les repères figurant ici tous produire des résultats INCORRECTS.
Laissez-moi vous expliquer:
La première chose que nous devons considérer est le compilateur JIT pour C# (.NET Framework 4). Maintenant, l'équipe produit du code natif pour le CPU à l'aide de différents algorithmes d'optimisation (qui ont tendance à être plus agressifs que la valeur par défaut C++ optimiseur fourni avec Visual Studio) et le jeu d'instructions utilisés par les .NET compilateur JIT sont plus près de la réflexion de l'effectif de la CPU sur la machine de sorte que certaines substitutions dans le code de l'ordinateur pourrait être fait pour réduire les temps de cycle et d'améliorer le taux de succès dans le PROCESSEUR pipeline de cache et de produire d'autres hyper-threading optimisations telles que la réorganisation de l'instruction et des améliorations relatives à la direction de la prévision.
Ce que cela signifie est que si vous compilez votre application C++ en utilisant la bonne pararmeters pour la version RELEASE (pas la version DEBUG) puis votre application C++ peut exécuter plus lentement que le correspondant de C# ou .NET en fonction de l'application. Lorsque vous spécifiez les propriétés du projet sur votre application C++, assurez-vous que vous activez l'option "optimisation" et "favoriser code rapide". Si vous avez un ordinateur 64 bits, vous DEVEZ spécifier à générer x64 comme la plate-forme cible, sinon, votre code sera exécuté par une conversion de la sous-couche (WOW64) qui permettra de réduire considérablement les performances.
Une fois que vous effectuez la bonne optimisations du compilateur, je reçois .72 secondes pour l'application C++ et 1,16 secondes pour l'application en C# (à la fois en version release). Depuis l'application en C# est très basique et alloue de la mémoire utilisée dans la boucle sur la pile et non pas sur le tas, c'est effectivement beaucoup mieux qu'une application réelle impliqués dans des objets lourds, de calculs et avec de plus grands ensembles de données. Donc, les chiffres fournis sont optimistes chiffres biaisés en faveur de C# et de la .NET framework. Même avec ce biais, l'application C++ termine en un peu plus de la moitié du temps que l'équivalent application en C#. Gardez à l'esprit que le compilateur C++ de Microsoft, j'ai utilisé n'a pas le droit de pipeline et l'hyperthreading optimisations (à l'aide de WinDBG pour afficher les instructions de montage).
Maintenant, si nous utilisons le compilateur Intel (qui est une industrie de secret pour générer des applications de haute performance sur AMD/Intel-processeurs), le même code s'exécute dans .54 secondes pour le C++ exécutable vs le .72 secondes à l'aide de Microsoft Visual Studio 2010. Donc en fin de compte, les résultats finaux sont .54 secondes pour C++ et 1,16 secondes pour C#. De sorte que le code produit par le .NET compilateur JIT prend 214% fois plus longtemps que le C++ exécutable. La plupart du temps passé dans la .54 secondes a été dans l'obtention de l'heure du système et non pas à l'intérieur de la boucle elle-même!
Ce qui manque aussi dans les statistiques est le démarrage et le nettoyage des temps qui ne sont pas inclus dans les horaires. Des applications C# ont tendance à passer beaucoup plus de temps au démarrage et lors de la résiliation que des applications C++. La raison derrière cela est compliqué et a à voir avec l' .NET runtime code des routines de validation et de la gestion de la mémoire sous-système qui effectue beaucoup de travail au début (et par conséquent, à la fin du programme afin d'optimiser les allocations de mémoire et le garbage collector.
Lors de la mesure de la performance de C++ et de .NET IL, il est important de regarder le code assembleur pour s'assurer que TOUS les calculs sont là. Ce que j'ai trouvé est que, sans mettre un peu de code supplémentaire en C#, la plupart du code dans les exemples ci-dessus ont été effectivement retiré de la binaire. Ce fut également le cas avec C++ lorsque vous avez utilisé une forme plus agressive de l'optimiseur tel que celui qui est fourni avec le compilateur Intel C++. Les résultats que j'ai fournis ci-dessus sont corrects à 100% et validé au niveau de l'assemblage.
Le principal problème avec beaucoup de forums sur internet que beaucoup de débutants écouter Microsoft marketing de la propagande sans la compréhension de la technologie et de faire de fausses déclarations que le C# est plus rapide que le C++. La revendication est que, en théorie, le C# est plus rapide que le C++ parce que le compilateur JIT peut optimiser le code pour le PROCESSEUR. Le problème avec cette théorie est que beaucoup de la plomberie qui existe dans le .NET framework qui ralentit la performance; de plomberie qui n'existe pas en C++ de l'application. En outre, un développeur expérimenté saura le droit compilateur à utiliser pour la plate-forme donnée et utiliser les indicateurs lors de la compilation de l'application. Sur Linux ou plates-formes open source, ce n'est pas un problème parce que vous pouvez distribuer votre source et de créer des scripts d'installation que de compiler le code à l'aide de l'optimisation approprié. Sur les fenêtres ou à code source fermé plate-forme, vous aurez à distribuer plusieurs exécutables, chacun avec des optimisations spécifiques. Les binaires pour windows qui seront déployées sont basés sur le PROCESSEUR détecté par le programme d'installation msi (à l'aide d'actions personnalisées).