C помітно швидший за C ++ [закрито]


83

Наскільки я розумію, усі мови сценаріїв та основні наукові програми, як правило, написані на мові C; це робить реалізацію безладною, але певним чином прямою.

Я розумію, що ці люди хотіли б максимізувати свою продуктивність, але чи існує реальна різниця між використанням рядків C та C-структур від використання класів C ++; Здається, C ++ працює так само, крім віртуальних функцій, він зберігає функцію класу один раз, і кожен екземпляр цього класу викликає цю одну функцію.

Що робить C швидшим і чи помітна різниця у проекті, такому як python або sqlite, який повинен бути найшвидшим?


9
"Ви повинні задавати лише практичні запитання, що відповідають, виходячи з реальних проблем, з якими ви стикаєтесь". - FAQ щодо stackoverflow.
RedGrittyBrick

2
"Добре написаний код будь-якою мовою завжди кращий, ніж погано написаний кодом будь-якою іншою мовою".
Kerrek SB

5
@Will - Ні. "Чи мова швидша за іншу мову", неможливо відповісти. Мови не швидкі, лише їх реалізація. "Чи швидше X реалізація мови, ніж Y іншої?" відповідає шляхом профілювання, але що ви профілюєте? Мовна реалізація може бути швидкою або повільною в різних сферах, і перевірити їх усі, безсумнівно, неможливо. Кращим запитанням було б "Чому дизайнери мов обирають мову X замість мови Y?" Це має чітку відповідь (обґрунтування, подане різними дизайнерами мов), і, швидше за все, буде корисним.
Chris Lutz,

3
Один і той же код у C та C ++ зазвичай повинен виконуватися з однаковою швидкістю, виняток становить код, який має різну семантику через різні правила псевдонімів тощо. Різниця між ідіомами C та ідіомами C ++. Якщо ви пишете код із найкращими ідіомами C на C або C ++, він, як правило, буде набагато легшим і швидшим (і матиме менше випадків відмов), ніж аналогічна функціональність, написана з найкращими ідіомами C ++ (незалежно від того, чи пишете ви це) на C або C ++), але для написання вам знадобиться набагато більше праці.
R .. GitHub СТОП ДОПОМОГАЙ ЛЕД

9
C значно швидше
засвоюється

Відповіді:


68

C ++ часто використовується для наукових програм. Популярність C може зменшуватися в цьому домені. Fortran залишається популярним як мова "низького рівня".

У C ++ "ви платите лише за те, що використовуєте". Отже, немає нічого, що могло б зробити це повільнішим, ніж С. Зокрема, для наукових програм шаблони виразів дозволяють виконати певну спеціальну оптимізацію за допомогою механізму шаблонів для обробки семантики програм.

Причиною того, що C є кращим для таких проектів, як Python, є те, що він, як правило, стає менш заплутаним для читання, тому велика кодова база буде доступнішою для більшої групи учасників.

SQLite має вимогу до невеликого розміру виконуваного коду, де C має невеликий край. Розумне використання C ++ все ще дозволяє використовувати його у вбудованих додатках, але він менш популярний через страх, що небажані мовні функції не потраплять.


10
Зверніть увагу, що C ++ дійсно керує іменами, де C ні, це полегшує іншим мовам прямий взаємодія з C. (swig фактично створює для вас інтерфейс C до коду C ++ до створення обгортки python для бібліотеки C ++.)
Сем П

8
@Samp C ++ має функцію , щоб відключити ім'я перекручуючи, extern "C". Swig випадково використовує C як мову мовної мови, але ви можете реалізувати цю обгортку в C-сумісному підмножині C ++ і ніколи не викликати компілятор C.
Potatoswatter

"SQLite має вимогу до невеликого розміру виконуваного коду, де C має невеликий край." Я не думаю, що SQLite, написаний на ідіоматичній мові C ++, був би дрібнішим або повільнішим за реалізацію C. Це, звичайно, було б набагато менше коду на C ++, і він міг би запропонувати необов’язкову попередню оптимізацію та компіляцію запитів під час компіляції. Для цього потрібен генератор коду, і, отже, за допомогою SQLITE ви не можете попередньо компілювати запити. C ++ SQLITE дозволить вам повторювати записи з діапазоном без будь-якого проміжного коду VM, і це зробить C SQLITE схожим на швидкість у порівнянні. Шкода ...
Куба не забув Моніку

Насправді, типовий вбудований додаток SQLITE з урахуванням розмірів має фіксований набір запитів, а база даних відображається з пам'яті з флеш-пам'яті з фіксованою схемою, а інтерпретатор SQL та віртуальна машина є мертвою вагою, як і багато іншого коду. Я провів кілька експериментів із написанням запитів із використанням "сирого" C, використовуючи низькорівневий доступ до сторінки в SQLITE, і для мого конкретного додатка я міг відкинути 85% коду SQLITE, більш-менш. Отже, якщо що, SQLITE втрачає великий час, не використовуючи C ++, але орієнтований на платформи, де немає доступного C ++, і вони не реалізували генератор коду C для запитів.
Куба не забув Моніку

@UnslanderMonica 1. Бінарні файли C ++ мають таблиці обробки винятків, які додають поле, навіть коли вони порожні. 2. SQLite базується на байт-коді. Оптимізація запитів під час компіляції в C ++ означала б синтаксичний аналіз та аналіз у функціях constexpr, які не можуть використовувати покажчики. Це свідчить про такі архітектурні зміни, що продукт більше не буде SQLite. 3. Чи не існує способу зберегти байт-код та видалити текст та синтаксичний аналізатор із двійкових файлів програми та бібліотеки? 4. SQLite без синтаксичного аналізатора або "безголовий" може взаємодіяти з генератором / оптимізатором байт-кодів, що містить лише заголовки C ++.
Potatoswatter

27

Я не думаю, що причина пов’язана настільки з продуктивністю, скільки зі сумісністю. Мова С ++ є більш складною, ніж мова С, але з точки зору продуктивності не повинно бути помітної різниці в будь-якому випадку. Деякі конструкції C ++ швидші за еквівалент C ( std::sortшвидше ніж qsort), і, мабуть, є хороші приклади навпаки.

РЕДАГУВАТИ: Що стосується взаємодії ...

В основному стандарт C ++ не визначає деяких речей, які можуть знадобитися для зручності взаємодії між двійковими файлами, створеними за допомогою різних компіляторів / версій. Найбільш помітним питанням тут було б узгодження імен символів у двійковому файлі. На мові C мова визначає єдине відображення кожного символу в коді до імені двійкового символу. Функція, що викликається my_function, створить символ у двійковому файлі, що викликається my_function. З іншого боку, і через такі функції, як перевантаження функцій, імена функцій C ++ повинні бути зіпсовані(переведено у різні символи функції у двійковому файлі, кодуючи типи аргументів та типи повернення), а стандарт не визначає, як виконується манґлінг. Це, в свою чергу, означає, що одну і ту ж функцію в C ++ можна скомпілювати до різних символів залежно від компілятора (якщо extern "C"це не використовується для примусової сумісності C для цих функцій у C ++).

Зрештою, інтерфейс між мовою сценаріїв та власним кодом у будь-якому випадку повинен бути інтерфейсом C, навіть якщо деталі того, як він реалізований внутрішньо, можуть бути C / C ++ / будь-якою іншою рідною мовою.

(Я навмисно не хочу вступати у полум’яну війну мовних приставок, С ++ дійсно потужний, але він також трохи страшний, оскільки це набагато складніша мова, ніж С, і деякі речі, які виглядають простими, можуть вплинути на продуктивність)


2
Думаю, можна впевнено сказати, що сучасний ідіоматичний C ++ вимагає інтелектуального компілятора, щоб у повній мірі скористатися вбудовуванням, RVO, постійним згортанням і т. Д. При цьому цілком можливо, що важкі конструкції C ++ взагалі не помітні на машинному рівні, але хороший компілятор набагато важливіший для C ++, ніж для C.
Kerrek SB

@Kerrek SB: Більшість сучасних компіляторів C ++ (де сучасні засоби означають останні пару років) дійсно добре ідентифікують ідіоматичні конструкції C ++ та оптимізують. Це std::sortодин із таких прикладів: std::lessфунктор, який використовується за замовчуванням, не менш ефективний, ніж еквівалентна функція C, але всі компілятори, яких я знаю, вбудують його (будучи шаблоном, він доступний для вбудовування) і видаляють усі виклики функції до compareфунктора.
Девід Родрігес - dribeas

Дивно, що бібліотека EASTL Electronic Arts частково виправдана твердженням, що вони вважають, що GCC погано вбудовується (а MSVC набагато кращий), і що, таким чином, для стандартної бібліотеки буде надто багато неоптимізованих викликів функцій. У EASTL вони використовують менше опосередкованих заходів для боротьби з цим. Хто знає, наскільки добре це міркування витримується в наш час.
Kerrek SB

13

Як згадував Бьярн у [D&E], ефективність є однією з головних цілей C ++. Отже, C ++ працює повільніше лише тоді, коли програміст використовує свої "додаткові" функції, такі як віртуальні функції, про які ви згадали, інформацію про rtt тощо

Тому я думаю, що це скоріше з психологічних причин - використовується C, оскільки він не допускає "повільних" функцій C ++.


9

Мови за своєю суттю не швидші і не повільніші, перекладачі та компілятори можуть бути більш-менш ефективними.

Крім того, мови вищого рівня забезпечують абстракційні рівні, які зазвичай мають вартість виконання. Якщо ви не використовуєте їх, компілятор може бути досить розумним, щоб їх видалити, але це може бути неможливим, якщо семантика мови не дозволяє зробити це безпечно ... А якщо вони вам потрібні, реалізуйте їх самостійно на мові нижчого рівня, можливо, буде повільніше, ніж на використанні "повільної" мови.


25
Мови сценаріїв успадковуються повільніше, ніж скомпільовані, якщо ви не пишете по-справжньому жахливому скомпільованому коді
Will03uk

2
@ Will03uk - Що заважає вам писати компілятор для зазвичай скриптової мови?
Chris Lutz,

6
@Chris, тоді це не була б мова сценарію; наслідки скриптової мови полягає в тому, що вона інтерпретується або компілюється байт-код. Після того, як ви скомпілюєте його, хіба це не компільована мова
Will03uk

1
це не вся правда: мовна семантика має значення, оскільки вони визначають інформацію, доступну оптимізатору, і які припущення можна безпечно зробити без необхідності проводити аналіз цілої програми; приклад: restrictключове слово на мові C або luajit - останнє не збиває з води всі інші vm для динамічних мов виключно тому, що Майк розумний хлопець, а також тому, що семантика Lua досить чиста (у порівнянні, наприклад, з JavaScript)
Крістоф

1
@Christoph Я намагаюся сказати, що срібної кулі немає. Якщо вам потрібні такі речі, як динамічна відправка, віртуальні дзвінки, гаряче завантаження коду або введення качки, мова, яка може здатися "повільною", якщо її виставити з коробки, можливо, швидше, ніж наївна реалізація в C.
fortran
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.