Багато з цих відповідей дають вагомі причини, чому C швидше чи ні (в цілому або в конкретних сценаріях). Безперечно, що:
- Багато інших мов надають автоматичні функції, які ми приймаємо як належне. Наприклад, перевірка меж, перевірка типу роботи та автоматичне управління пам'яттю, наприклад, не приходять безкоштовно. Існує хоча б якась вартість, пов’язана з цими функціями, про яку ми можемо не думати - а то й усвідомлювати - під час написання коду, який використовує ці функції.
- Крок від джерела до машини часто не є таким прямим в інших мовах, як на C.
- OTOH, якщо сказати, що компільований код C виконується швидше, ніж інший код, написаний іншими мовами, - це узагальнення, яке не завжди відповідає дійсності. Контрприклади легко знайти (або надумати).
Незважаючи на все це, є щось інше, що я помітив, що, я думаю, впливає на порівняльну ефективність С порівняно з багатьма іншими мовами сильніше, ніж будь-який інший фактор. А саме:
Інші мови часто спрощують писати код, який виконується повільніше. Часто його навіть заохочують дизайнерські філософії мови. Слідство: програміст на С більше схильний писати код, який не виконує зайвих операцій.
Як приклад, розглянемо просту програму Windows, в якій створено єдине головне вікно. Версія змінного струму заповнює WNDCLASS[EX]
структуру, якій буде передано RegisterClass[Ex]
, а потім дзвонить CreateWindow[Ex]
і вводить цикл повідомлень. Наступний високо спрощений та скорочений код:
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);
}
Еквівалентною програмою на C # може бути лише один рядок коду:
Application.Run(new Form());
Цей один рядок коду надає всю функціональність, яку зробили майже 20 рядків коду С, і додає деякі речі, які ми залишили поза увагою, наприклад перевірку помилок. Багатіша, повніша бібліотека (порівняно з тими, що використовуються в типовому проекті C) зробила багато роботи для нас, звільнивши час на написання ще багатьох фрагментів коду, які нам здаються короткими, але залучають багато кроків за кадром.
Але багата бібліотека, що дозволяє легко та швидко розкривати код, насправді не моє значення. Моя думка є більш очевидною, коли ви починаєте вивчати, що насправді відбувається, коли насправді виконує наш маленький лайнер. Для задоволення колись увімкніть доступ до джерела .NET у Visual Studio 2008 або новішої версії, а потім перейдіть до простого рядка вище. Один із найцікавіших маленьких дорогоцінних каменів, які ви зустрінете, - це коментар у геттері для 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();
}
Десять разів . Інформація, приблизно еквівалентна сумі того, що зберігається в WNDCLASSEX
структурі, і що передано CreateWindowEx
, отримується з Control
класу в десять разів, перш ніж вона зберігається в WNDCLASSEX
структурі і передається в RegisterClassEx
і CreateWindowEx
.
Загалом, кількість вказівок, виконаних для виконання цього найважливішого завдання, на 2–3 порядки більше на C #, ніж у C. Частина цього пов'язана з використанням багатофункціональної бібліотеки, яка обов'язково узагальнена, порівняно з наш простий код C, який робить саме те, що нам потрібно, і більше нічого. Але його частина пов’язана з тим, що модульований, об'єктно-орієнтований характер .NET-рамки піддається безлічі повторень виконання, що часто уникається процедурним підходом.
Я не намагаюся вибирати на C # або .NET Framework. Я також не кажу, що модуляризація, узагальнення, особливості бібліотеки / мови, OOP тощо - це погані речі . Більшу частину своєї роботи я раніше робив на C, пізніше на C ++, а останнім часом на C #. Аналогічно до C я використовував переважно збірку. І з кожним кроком "вище" мою мову йде, я пишу кращі, більш рентабельні, більш надійні програми за менший час. Однак вони, як правило, виконують трохи повільніше.