Beaucoup de ces réponses donnent des raisons valables pour lesquelles C est, ou n'est pas, plus rapide (en général ou dans des scénarios spécifiques). Il est indéniable que:
- De nombreuses autres langues proposent des fonctionnalités automatiques que nous tenons pour acquises. La vérification des limites, la vérification du type au moment de l'exécution et la gestion automatique de la mémoire, par exemple, ne sont pas gratuites. Il y a au moins un certain coût associé à ces fonctionnalités, auquel nous ne pouvons pas penser - ou même réaliser - lors de l'écriture de code qui utilise ces fonctionnalités.
- Le pas de la source à la machine n'est souvent pas aussi direct dans les autres langues qu'en C.
- OTOH, dire que le code C compilé s'exécute plus rapidement que les autres codes écrits dans d'autres langages est une généralisation qui n'est pas toujours vraie. Les contre-exemples sont faciles à trouver (ou à inventer).
Malgré tout cela, il y a autre chose que j'ai remarqué qui, je pense, affecte la performance comparative de C par rapport à de nombreux autres langages plus que tout autre facteur. En être témoin:
D'autres langages facilitent souvent l'écriture de code qui s'exécute plus lentement. Souvent, il est même encouragé par les philosophies de conception de la langue. Corollaire: un programmeur C est plus susceptible d'écrire du code qui n'effectue pas d'opérations inutiles.
Par exemple, considérons un simple programme Windows dans lequel une seule fenêtre principale est créée. La version AC remplirait une WNDCLASS[EX]
structure qui serait passée à RegisterClass[Ex]
, puis appeler CreateWindow[Ex]
et entrer une boucle de message. Le code très simplifié et abrégé suit:
WNDCLASS wc;
MSG msg;
wc.style = 0;
wc.lpfnWndProc = &WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = "MainWndCls";
RegisterClass(&wc);
CreateWindow("MainWndCls", "", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
while(GetMessage(&msg, NULL, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Un programme équivalent en C # pourrait être une seule ligne de code:
Application.Run(new Form());
Cette ligne de code fournit toutes les fonctionnalités de près de 20 lignes de code C et ajoute certaines choses que nous avons omises, telles que la vérification des erreurs. La bibliothèque plus riche et plus complète (par rapport à celles utilisées dans un projet C typique) a fait beaucoup de travail pour nous, nous laissant ainsi le temps d'écrire de nombreux extraits de code qui nous paraissent courts mais qui impliquent de nombreuses étapes en arrière-plan.
Mais une bibliothèque riche permettant un ballonnement de code facile et rapide n'est pas vraiment mon point. Mon point est plus apparent lorsque vous commencez à examiner ce qui se passe réellement lorsque notre petit one-liner s'exécute. Pour le plaisir, parfois, activez l'accès aux sources .NET dans Visual Studio 2008 ou supérieur, et entrez dans le simple one-linef ci-dessus. L'un des petits joyaux amusants que vous rencontrerez est ce commentaire dans le getter pour Control.CreateParams
:
// In a typical control this is accessed ten times to create and show a control.
// It is a net memory savings, then, to maintain a copy on control.
//
if (createParams == null) {
createParams = new CreateParams();
}
Dix fois . Les informations à peu près équivalentes à la somme de ce qui est stocké dans une WNDCLASSEX
structure et de ce qui est transmis CreateWindowEx
sont extraites de la Control
classe dix fois avant d' être stockées dans une WNDCLASSEX
structure et transmises à RegisterClassEx
et CreateWindowEx
.
Dans l'ensemble, le nombre d'instructions exécutées pour effectuer cette tâche très basique est de 2 à 3 ordres de grandeur de plus en C # qu'en C. Une partie de cela est due à l'utilisation d'une bibliothèque riche en fonctionnalités, qui est nécessairement généralisée, par rapport à notre simple code C qui fait exactement ce dont nous avons besoin et rien de plus. Mais cela est dû en partie au fait que la nature modulaire et orientée objet du framework .NET se prête à de nombreuses répétitions d'exécution qui sont souvent évitées par une approche procédurale.
Je n'essaye pas de choisir C # ou le framework .NET. Je ne dis pas non plus que la modularisation, la généralisation, les fonctionnalités de bibliothèque / langage, la POO, etc. sont de mauvaises choses . J'ai utilisé pour faire la plupart de mon développement en C, plus tard en C ++, et plus récemment en C #. De même, avant C, j'utilisais principalement l'assemblage. Et à chaque étape «plus haut» de ma langue, j'écris des programmes meilleurs, plus faciles à maintenir et plus robustes en moins de temps. Ils ont cependant tendance à s'exécuter un peu plus lentement.