Viele dieser Antworten geben gültige Gründe dafür an, warum C schneller ist oder nicht (entweder im Allgemeinen oder in bestimmten Szenarien). Es ist nicht zu leugnen, dass:
- Viele andere Sprachen bieten automatische Funktionen, die wir für selbstverständlich halten. Die Überprüfung von Grenzen, die Überprüfung des Laufzeit-Typs und die automatische Speicherverwaltung sind beispielsweise nicht kostenlos. Mit diesen Funktionen sind zumindest einige Kosten verbunden, die wir beim Schreiben von Code, der diese Funktionen verwendet, möglicherweise nicht berücksichtigen oder gar nicht realisieren.
- Der Schritt von der Quelle zur Maschine ist in anderen Sprachen oft nicht so direkt wie in C.
- OTOH, zu sagen, dass kompilierter C-Code schneller ausgeführt wird als anderer in anderen Sprachen geschriebener Code, ist eine Verallgemeinerung, die nicht immer wahr ist. Gegenbeispiele sind leicht zu finden (oder zu erfinden).
Ungeachtet dessen ist mir noch etwas anderes aufgefallen, das meiner Meinung nach die Vergleichsleistung von C im Vergleich zu vielen anderen Sprachen stärker beeinflusst als jeder andere Faktor. Nämlich:
Andere Sprachen erleichtern häufig das Schreiben von Code, der langsamer ausgeführt wird. Oft wird es sogar durch die Designphilosophien der Sprache gefördert. Folgerung: Ein C-Programmierer schreibt eher Code, der keine unnötigen Operationen ausführt.
Stellen Sie sich als Beispiel ein einfaches Windows-Programm vor, in dem ein einzelnes Hauptfenster erstellt wird. Die AC-Version würde eine WNDCLASS[EX]
Struktur füllen, an die übergeben würde RegisterClass[Ex]
, dann aufrufen CreateWindow[Ex]
und eine Nachrichtenschleife eingeben. Es folgt ein stark vereinfachter und abgekürzter Code:
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);
}
Ein äquivalentes Programm in C # kann nur eine Codezeile sein:
Application.Run(new Form());
Diese eine Codezeile bietet alle Funktionen, die fast 20 Zeilen C-Code bieten, und fügt einige Dinge hinzu, die wir ausgelassen haben, z. B. die Fehlerprüfung. Die reichhaltigere, umfassendere Bibliothek (im Vergleich zu den in einem typischen C-Projekt verwendeten) hat viel Arbeit für uns geleistet und uns Zeit gelassen, viel mehr Codefragmente zu schreiben, die für uns kurz aussehen, aber viele Schritte hinter die Kulissen beinhalten.
Aber eine umfangreiche Bibliothek, die einfaches und schnelles Aufblähen von Code ermöglicht, ist nicht wirklich mein Punkt. Mein Punkt wird deutlicher, wenn Sie untersuchen, was tatsächlich passiert, wenn unser kleiner Einzeiler tatsächlich ausgeführt wird. Aktivieren Sie zum Spaß manchmal den .NET -Quellzugriff in Visual Studio 2008 oder höher und gehen Sie in die einfache einzeilige Zeile oben. Eines der lustigen kleinen Juwelen, auf das Sie stoßen werden, ist dieser Kommentar im Getter für 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();
}
Zehnmal . Die Information entspricht in etwa der Summe dessen , was in einer gespeichert ist WNDCLASSEX
Struktur und was übergeben wird CreateWindowEx
von den abgerufen Control
Klasse zehnmal , bevor es in einer gespeichert ist WNDCLASSEX
Struktur und an RegisterClassEx
und CreateWindowEx
.
Alles in allem beträgt die Anzahl der Befehle, die zur Ausführung dieser sehr grundlegenden Aufgabe ausgeführt werden, in C # 2–3 Größenordnungen mehr als in C. Ein Teil davon ist auf die Verwendung einer funktionsreichen Bibliothek zurückzuführen, die notwendigerweise verallgemeinert ist unser einfacher C-Code, der genau das tut, was wir brauchen und nichts weiter. Ein Teil davon ist jedoch auf die Tatsache zurückzuführen, dass sich die modularisierte, objektorientierte Natur von .NET Framework für viele Wiederholungen der Ausführung eignet, die häufig durch einen prozeduralen Ansatz vermieden werden.
Ich versuche nicht, C # oder das .NET-Framework auszuwählen. Ich sage auch nicht, dass Modularisierung, Generalisierung, Bibliotheks- / Sprachfunktionen, OOP usw. schlechte Dinge sind . Ich habe den größten Teil meiner Entwicklung in C, später in C ++ und zuletzt in C # durchgeführt. In ähnlicher Weise habe ich vor C hauptsächlich Montage verwendet. Und mit jedem Schritt "höher" meiner Sprache schreibe ich bessere, wartbarere und robustere Programme in kürzerer Zeit. Sie neigen jedoch dazu, etwas langsamer auszuführen.