Почему C настолько же быстро, и почему не другие языки как быстро или быстрее?

В слушании подкаста StackOverflow удар продолжает подходить, который "настоящие программисты" пишут в C, и что C настолько быстрее, потому что это "близко к машине". Оставляя бывшее утверждение для другого сообщения, что является особенным о C, который позволяет ему быть быстрее, чем другие языки? Или помещенный иначе: что должно остановить другие языки от способности скомпилировать вниз в двоичный файл, который работает столь же быстро как C?

202
задан yaitloutou 6 December 2016 в 19:07
поделиться

26 ответов

нет очень, это является особенным о C. Это - одна из причин, почему это быстро.

Более новые языки, которые имеют поддержку сборка "мусора" , динамический контроль типов и другие средства, которые облегчают для программиста писать программы.

выгода, существует дополнительная обработка наверху, которая ухудшит производительность приложения. C не имеет, любой из которых, что означает, что нет никаких издержек, но который означает, что программист должен быть в состоянии выделить память и освободить их для предотвращения утечки памяти , и должен иметь дело со статическим контролем типов переменных.

Однако много языков и платформ, таких как Java (с виртуальная машина Java ) и.NET (с ее Общеязыковой средой выполнения) улучшили производительность за эти годы с появлениями такой как своевременная компиляция , который производит собственный машинный код из байт-кода для достижения более высокой производительности.

196
ответ дан Sebastian Karlsson 23 November 2019 в 04:59
поделиться

Даже различие между C и C++ может время от времени быть большим.

при выделении памяти для объекта, вызывая конструкторов, выравнивая память на границах слова, и т.д. программа завершает прохождение через большого количества издержек, которые абстрагированы далеко от программиста.

C вынуждает Вас смотреть на каждую вещь, которую Ваша программа делает, обычно на очень прекрасный уровень детализации. Это делает его тяжелее (хотя ни в коем случае не невозможным) для записи кода, который делает много задач, которые являются ненужными к непосредственной цели под рукой.

Поэтому, где в, например, ОСНОВНАЯ программа Вы использовали бы ВХОДНОЕ ключевое слово для чтения строки, формируют STDIN и автоматически выделяют память для ее переменной, в C, программист будет обычно уже выделять память и может управлять вещами как то, ли блоки программы для ввода-вывода или нет, и если это прекращает читать вход после того, как это имеет информацию, в которой это нуждается или продолжает читать символы до конца строки.

C также выполняет намного меньше проверки ошибок, чем другие языки, предполагая, что программист знает то, что они делают. Таким образом, тогда как в PHP, если Вы объявляете строку $myStr = getInput(); и переходите к ссылке $myStr[20], но вход был только 10 символами долго, PHP поймает это и безопасно возвратит Вам пустую строку. C предполагает или выделение достаточной памяти для содержания данных мимо конца строки или что Вы знаете, какая информация прибывает после строки и пытается сослаться на это вместо этого. Эти маленькие факторы оказывают огромное влияние на издержки в агрегате.

0
ответ дан 2 revs 23 November 2019 в 04:59
поделиться

1) Как другие сказали, C делает меньше для Вас. Никакие переменные инициализации, никакой массив не ограничивает проверку, никакое управление памятью, и т.д. Те функции на других языках стоят памяти и циклов ЦП, которые не тратит C.

2) Ответы, говоря, что C менее абстрактен и поэтому быстрее, являются только половиной корректного, я думаю. С технической точки зрения, если бы у Вас был "достаточно усовершенствованный компилятор" для языка X, затем язык X мог приблизиться или равняться скорости C. Различие с C то, что, так как он отображается так, очевидно (при взятии курса архитектуры) и непосредственно к ассемблеру, что даже наивный компилятор может сделать достойное задание. Для чего-то как Python Вам нужен очень усовершенствованный компилятор, чтобы предсказать вероятные типы объектов и генерировать машинный код на лету - семантика C достаточно проста, что может преуспеть простой компилятор.

1
ответ дан Joseph Garvin 23 November 2019 в 04:59
поделиться

С современными оптимизирующими компиляторами очень маловероятно, что чистая программа C будет всем этим намного быстрее, чем скомпилированный код .net, если вообще. С улучшением производительности, которое платформы как .net предоставляют разработчику, можно сделать вещи через день, который раньше занимал недели или месяцы в регулярном C. Вместе с дешевой стоимостью аппаратных средств по сравнению с зарплатой разработчика всего ПУТЬ более дешево записать материал на высокоуровневом языке и бросить аппаратные средства в любое замедление.

причина Jeff и разговор Joel о C быть "настоящим программистом" язык - то, потому что нет никакого содержания руки в C. Необходимо выделить собственную память, освободить ту память, сделать собственную проверку границ и т.д. Нет такой вещи как новый объект (); нет никакой сборки "мусора", классов, ООП, платформ объекта, LINQ, свойств, атрибутов, полей или чего-либо как этот. Необходимо знать вещи как адресная арифметика с указателями и как разыменовать указатель. И в этом отношении знайте и поймите, каков указатель. Необходимо знать то, что стековый фрейм и каков указатель команд. Необходимо знать модель памяти архитектуры ЦП, Вы продолжаете работать. Существует большое неявное понимание архитектуры микрокомпьютера (обычно микрокомпьютер, Вы продолжаете работать) при программировании в C, который просто не присутствует, ни необходим при программировании в чем-то как C# или Java. Вся та информация была разгружена к компилятору (или VM) программист.

1
ответ дан Robert C. Barth 23 November 2019 в 04:59
поделиться

Некоторые алгоритмы C++ быстрее, чем C, и некоторые реализации алгоритмов или шаблонов разработки на других языках могут быть быстрее, чем C.

, Когда люди говорят, что C быстр, и затем идет дальше к разговору о некотором другом языке, они обычно используют работу C в качестве сравнительного теста.

1
ответ дан Arafangion 23 November 2019 в 04:59
поделиться

Назад в хорошие ole дни, было всего два типа языков: скомпилированный и интерпретируемый.

Скомпилированные языки использовали "компилятор", чтобы считать синтаксис языка и преобразовать его в идентичный код ассемблера, который мог, чем просто непосредственно на ЦП. Интерпретируемые языки использовали несколько различных схем, но по существу синтаксис языка был преобразован в промежуточную форму, и затем выполнен в "интерпретаторе", среде для того, чтобы выполнить код.

Таким образом, в некотором смысле, был другой "слой" - интерпретатор - между кодом и машиной. И, как всегда случай в компьютере, большем количестве средств больше ресурсов привыкает. Интерпретаторы были медленнее, потому что они должны были выполнить больше операций.

Позже, мы видели больше гибридных языков как Java, которые используют и компилятор и интерпретатор, чтобы заставить их работать. Это сложно, но JVM быстрее, более сложна и путь, более оптимизированный, чем старые интерпретаторы, таким образом, это выдерживает намного лучшее изменение выполнения (со временем) ближе только к прямому скомпилированному коду. Конечно, более новые компиляторы также имеют более необычные приемы оптимизации, таким образом, они имеют тенденцию генерировать путь, лучше кодируют, чем они привыкли для также. Но большая часть оптимизации, чаще всего (хотя не всегда) делает некоторый тип компромисса таким образом, что они находятся не всегда быстрее при всех обстоятельствах. Как все остальное, ничто не прибывает бесплатно, таким образом, оптимизаторы должны получить свое хвастовство от где-нибудь (хотя часто времена это использующий ЦП времени компиляции для сохранения ЦП во время выполнения).

Возвращение к C, это - простой язык, который может быть скомпилирован в справедливо оптимизированный блок и затем выполнен непосредственно на целевой машине. В C при постепенном увеличении целого числа более, чем вероятно, что это - только один ассемблерный шаг в ЦП в Java однако, это могло закончить тем, что было намного больше, чем тот (и мог включать немного сборки "мусора" также:-), C, предлагает Вам абстракцию, которая является путем ближе к машине (ассемблер является самым близким), но Вы заканчиваете тем, что имели необходимость сделать путь больше работы для получения его движение, и это как не защищено, не просто в использовании или дружественная ошибка. Большинство других языков дает Вам более высокую абстракцию и заботится о большем количестве базовых деталей для Вас, но в обмен на их передовую функциональность они требуют, чтобы больше ресурсов работало. Поскольку Вы обобщаете некоторые решения, необходимо обработать более широкий диапазон вычисления, которое часто требует большего количества ресурсов.

Paul.

2
ответ дан Paul W Homer 23 November 2019 в 04:59
поделиться

Самый быстрый рабочий код был бы тщательно машинным кодом ручной работы. Ассемблер будет почти как хороший. Оба - очень низкий уровень, и требуется большая запись кода, чтобы сделать вещи. C немного выше ассемблера. У Вас все еще есть способность управлять вещами на очень низком уровне в фактической машине, но существует достаточно абстракции, делают запись его быстрее и легче тогда ассемблер. Другие языки, такие как C# и JAVA еще более абстрактны. В то время как Ассемблерный и машинный код называют низкоуровневыми языками, C# и JAVA (и многие другие) называют высокоуровневыми языками. C иногда называют языком среднего уровня.

4
ответ дан Jim C 23 November 2019 в 04:59
поделиться

Я знаю, что много людей сказало это длинным обветренным способом, но:

C быстрее, потому что он делает меньше (для Вас).

6
ответ дан Daemin 23 November 2019 в 04:59
поделиться

Основные факторы - то, что это - статически типизированный язык, и это компилируется в машинный код. Кроме того, так как это - низкоуровневый язык, это обычно не делает ничего, чему Вы не говорите его.

Это некоторые другие факторы, которые приходят на ум.

  • Переменные автоматически не инициализируются
  • Никакие границы, проверяющие массивы
  • управление указателем Непроверенное
  • Никакое целочисленное переполнение, проверяющее
  • переменные Со статическим контролем типов
  • , Вызовы функции статичны (если Вы не используете указатели функции)
  • , у Разработчиков компилятора было много времени для улучшения кода оптимизации. Кроме того, люди программируют в C в целях получения лучшей производительности, таким образом, существует давление для оптимизации кода.
  • Части спецификации языка определяются реализацией, таким образом, компиляторы являются бесплатными сделать вещи самым оптимальным способом

, Большинство статических типизированных языков могло быть скомпилировано столь же быстро или быстрее, чем C, хотя, особенно если они могут сделать предположения, что C не может из-за искажения указателя, и т.д.

8
ответ дан Matthew Crumley 23 November 2019 в 04:59
поделиться

Удивительный для наблюдения старого "C/C++ должен быть быстрее, чем Java, потому что Java интерпретируется" миф, является все еще живым и здоровым. Существуют статьи, возвращающиеся несколько лет , а также более свежие , которые объясняют с понятиями или измерениями, почему это просто не всегда имеет место .

Текущие реализации виртуальной машины (и не только JVM, между прочим) могут использовать в своих интересах информацию, собранную во время выполнения программы для динамичной настройки кода, когда это работает, с помощью множества методов:

  • представляющие частые методы к машинному коду,
  • встраивающие маленькие методы,
  • корректировка блокировки

и множество других корректировок на основе знания, что код на самом деле делает, и на фактических характеристиках среды, в которой это работает.

4
ответ дан joel.neely 23 November 2019 в 04:59
поделиться

Это не так о языке как инструменты и библиотеки. Доступные библиотеки и компиляторы для C значительно старше, чем для более новых языков. Вы могли бы думать, что это сделает их медленнее, но напротив.

Эти библиотеки были записаны в то время, когда вычислительная мощность и память были в большом почете. Они должны были быть записаны очень эффективно для работы вообще. У разработчиков компиляторов C также было долгое время для работы во всех видах умной оптимизации для различных процессоров. Зрелость C и широкое принятие делают для преимущества signficant перед другими языками того же возраста. Это также дает C преимущество скорости перед более новыми инструментами, которые не подчеркивают необработанную производительность так же, как C имел к.

4
ответ дан Dave Swersky 23 November 2019 в 04:59
поделиться

Это - на самом деле определенная увековеченная ложность. В то время как это верно, что программы C часто быстрее, это не всегда имеет место, особенно если программист C не очень хорош в нем.

Одна большая явная дыра, о которой люди склонны забывать, - когда программа должна заблокироваться для своего рода IO, такого как ввод данных пользователем в любой программе GUI. В этих случаях действительно не имеет значения, какой язык Вы используете, так как Вы ограничены уровнем, на котором могут войти данные, а не как быстро можно обработать его. В этом случае не имеет значения очень при использовании C, Java, C# или даже Perl; Вы просто не можете пойти немного быстрее, чем данные могут войти.

другая главная вещь состоит в том, что использование сборки "мусора" и не использование надлежащих указателей позволяют виртуальной машине делать много оптимизации не доступными на других языках. Например, JVM способна к перемещению объектов на "куче" для дефрагментации его. Это делает будущие выделения намного быстрее, так как следующий индекс может просто использоваться вместо того, чтобы искать его в таблице. Современные JVMs также не должны на самом деле освобождать память; вместо этого, они просто перемещают живые объекты вокруг, когда они GC и потраченная память от мертвых объектов восстанавливаются по существу бесплатно.

Это также поднимает интересный момент о C и еще больше в C++. Существует что-то вроде принципов проектирования, "Если Вам не нужно оно, Вы не платите за него". Проблема состоит в том, что, если Вы действительно хотите его, Вы заканчиваете тем, что платили бешеные деньги за него. Например, vtable реализация в Java имеет тенденцию быть намного лучше, чем реализации C++, таким образом, вызовы виртуальной функции намного быстрее. С другой стороны, у Вас нет выбора, кроме как использовать виртуальные функции в Java, и они все еще стоят чего-то, но в программах, которые используют много виртуальных функций, уменьшенная стоимость складывает.

5
ответ дан James 23 November 2019 в 04:59
поделиться

По большей части каждая инструкция C соответствует очень немногим ассемблерным инструкциям. Вы по существу пишете высокоуровневый машинный код, таким образом, Вы управляете почти всем, что процессор делает. Много других скомпилированных языков, таких как C++, имеют много просто выглядящих инструкций, которые могут превратиться в намного большее количество кода, чем Вы думаете, что это делает (виртуальные функции, скопируйте конструкторов и т.д.) И интерпретируемые языки как Java или Ruby имеют другой слой инструкций, что Вы никогда не видите - Виртуальная машина или Интерпретатор.

5
ответ дан AShelly 23 November 2019 в 04:59
поделиться

Я предполагаю, что Вы забыли, что Ассемблер является также языком:)

, Но серьезно, C программы быстрее только, когда программист знает то, что он делает. Можно легко записать программу C, которая работает медленнее, чем программы, записанные на других языках, которые делают то же задание.

причина, почему C быстрее, состоит в том, потому что это разработано таким образом. Это позволяет Вам сделать большой "более низкий уровень" материал, который помогает компилятору оптимизировать код. Или, будем мы говорить, Вы, программист ответственен за оптимизацию кода. Но это часто довольно хитро и подвержено ошибкам.

Другие языки, как другие уже упомянули, сфокусируйтесь больше на производительности программиста. Обычно считается, что время программиста намного более дорогое, чем машинное время (даже в былые времена). Таким образом, это имеет много смысла минимизировать программистов времени, тратят на запись и отладку программ вместо времени выполнения программ. Чтобы сделать это, Вы пожертвуете немного на том, что можно сделать для создания программы быстрее, потому что много вещей автоматизировано.

8
ответ дан PolyThinker 23 November 2019 в 04:59
поделиться

Отсутствие абстракции - то, что делает C быстрее. Если Вы пишете оператор вывода, Вы знаете точно, что происходит. Если Вы пишете оператор вывода в Java, это становится скомпилированным в файл класса, на котором тогда работают виртуальная машина, представляющая слой абстракции. Отсутствие объектно-ориентированных функций как часть языка также увеличивается, это - скорость, делают для меньше кодирования быть сгенерированным. Если Вы используете C в качестве объектно-ориентированного языка тогда, Вы делаете все кодирование для вещей, таких как классы, inharitence, и т.д. Это означает, скорее тогда делают, что-то сделало вывод достаточно для всех с объемом кода и штрафом производительности, который требует, чтобы Вы только записали то, что необходимо было сделать задание.

4
ответ дан Jared 23 November 2019 в 04:59
поделиться

, что должно остановить другие языки от способности скомпилировать вниз в двоичный файл, который работает столь же быстро как C?

Ничто. Современные языки как Java или.NET langs ориентированы больше на производительности программиста, а не производительности. Аппаратные средства являются дешевыми теперь дни. Также компиляция к промежуточному представлению дает много премий, таких как безопасность, мобильность и т.д. CLR.NET может использовать в своих интересах различные аппаратные средства - например, Вы не должны вручную оптимизировать/перекомпилировать программу для использования набора инструкций SSE.

11
ответ дан aku 23 November 2019 в 04:59
поделиться

C не всегда быстрее.

C медленнее, чем, например, современный Фортран.

C часто медленнее, чем Java для некоторых вещей. (Особенно после того, как JIT-компилятор делал попытку Вашего кода)

, C позволяет искажению указателя произойти, что означает, что некоторая хорошая оптимизация не возможна. Особенно, когда у Вас есть несколько модулей выполнения, это вызывает остановы выборки данных. Ой.

предположение, что работы адресной арифметики с указателями действительно вызывают медленную чрезмерно увеличенную в размерах производительность на некоторых семьях CPU (PIC особенно!) Это раньше сосало большое на сегментированном x86.

В основном, когда Вы получаете векторную единицу, или компилятор параллелизации, C воняет, и современный Фортран работает быстрее.

программист C обманывает как преобразование (изменяющий исполняемый файл на лету) остановы упреждающей выборки ЦП причины.

Вы получаете дрейф?

И наш хороший друг, x86, выполняет систему команд, которая в эти дни имеет мало отношения к фактической архитектуре ЦП. Теневые регистры, оптимизаторы загрузки и хранения, все в ЦП. Таким образом, C тогда близко к виртуальному металлу. Реальный металл, Intel не позволяет Вам видеть. (Исторически ЦП VLIW был чем-то вроде промаха так, возможно, это не так плохо.)

, Если Вы программируете в C на высокоэффективном DSP (возможно, DSP TI?), компилятор должен сделать некоторый хитрый материал для разворачивания C через несколько параллельных модулей выполнения. Таким образом, в этом случае C не близко к металлу, но именно близко к компилятору, сделает целую оптимизацию программы. Странный.

И наконец, некоторые центральные процессоры (www.ajile.com) выполняют Байт-коды Java в аппаратных средствах. C был бы ЛАВАШ для использования на том ЦП.

19
ответ дан PProteus 23 November 2019 в 04:59
поделиться

Это не так, что C быстр как, что модель стоимости C прозрачна . Если программа C является медленной, это медленно очевидным способом: путем выполнения большого количества операторов. По сравнению со стоимостью операций в C высокоуровневые операции на объектах (особенно отражение) или строки могут иметь затраты, которые не очевидны.

Два языка, которые обычно компилируют в двоичные файлы, которые так же быстры, как C являются Стандартным ML (использующий компилятор MLton ) и Объективный Caml. Если Вы проверите игра сравнительных тестов, то Вы найдете, что для некоторых сравнительных тестов, как двоичные деревья, версия OCaml быстрее, чем C. (Я не нашел записей MLton.), Но не относятся к перестрелке слишком серьезно; это, как это говорит, игра, результаты часто отражаются, насколько люди усилия вставили настройку кода.

31
ответ дан igouy 23 November 2019 в 04:59
поделиться

Существует много вопросов там - главным образом, на которые я не квалифицирован для ответа. Но для этого последнего:

, что должно остановить другие языки от способности скомпилировать вниз в двоичный файл, который работает столь же быстро как C?

, Одним словом, Абстракция.

C является только одним или 2 уровнями абстракции далеко от машинного языка. Java и.Net языки являются как минимум 3 уровнями абстракции далеко от ассемблера. Я не уверен в Python и Ruby.

Как правило, чем должно быть сделано больше игрушек программиста (сложные типы данных, и т.д.), тем далее Вы с машинного языка и большего количества перевода.

я прочь тут и там, но это - основная суть.

Обновление -------Существуют некоторые хорошие комментарии к этому сообщению с большим количеством деталей.

36
ответ дан Community 23 November 2019 в 04:59
поделиться

Я уже не видел его, таким образом, я скажу это: C имеет тенденцию быть быстрее, потому что почти все остальное записано в C.

Java основан на C, Python основан на C (или Java или.NET, и т.д.), Perl, и т.д. ОС записана в C, виртуальные машины записаны в C, компиляторы записаны в C, интерпретаторы записаны в C. Некоторые вещи все еще записаны в Ассемблере, который имеет тенденцию быть еще быстрее. Все больше вещей пишется в чем-то еще, которое самостоятельно записано в C.

Каждый оператор, который Вы пишете на других языках (не блок) обычно реализуется внизу как несколько операторов в C, которые компилируются вниз в собственный машинный код. Так как те другие языки имеют тенденцию существовать для получения более высокого уровня абстракции, чем C, те дополнительные операторы, требуемые в C, имеют тенденцию быть сфокусированными на добавляющей безопасности, добавляя сложность, и обеспечивая обработку ошибок. Те часто - хорошие вещи, но они имеют , стоит , и его имена скорость и размер .

Лично, я записал на буквально десятках языков, охватывающих большую часть доступного спектра, и я лично искал волшебство, что Вы намекаете:

, Как я могу иметь свой пирог и съесть его, также? Как я могу играть с высокоуровневыми абстракциями на своем любимом языке, тогда выпадающем к вшивому песчаному из C для скорости?

После нескольких лет исследования, моим ответом является Python (на C). Вы могли бы хотеть посмотреть на него. Между прочим, Вы можете также выпадающий к блоку из Python, также (с некоторой незначительной справкой из специальной библиотеки).

, С другой стороны, плохой код может быть записан на любом языке . Поэтому C (или блок) код не автоматически быстрее. Аналогично, некоторые приемы оптимизации могут принести части из высокоуровневого кода языка близко к уровню производительности сырых данных C. Но для большинства приложений Ваша программа проводит большую часть своего времени, ожидая на людях или аппаратных средствах, таким образом, различие действительно не имеет значения.

Обладают.

48
ответ дан Rob Williams 23 November 2019 в 04:59
поделиться

Если Вы проводите месяц для создания чего-то в C, который работает через 0,05 секунды, и я провожу день, пишущий то же самое в Java, и это работает через 0,10 секунды, то является C действительно быстрее?

, Но отвечать на Ваш вопрос, правильно написанный код C будет обычно работать быстрее, чем правильно написанный код на других языках, потому что часть записи C код "хорошо" включает выполнение ручной оптимизации в уровень почти машины.

, Хотя компиляторы очень умны действительно, они еще не в состоянии творчески придумать код, который конкурирует с массажировавшими рукой алгоритмами (предполагающий, что "руки" принадлежат хороший программист C).

Редактирование:

Много комментариев вроде, "Я пишу в C, и я не думаю об оптимизации".

, Но взять определенный пример из этого сообщения :

В Дельфи я мог записать это:

function RemoveAllAFromB(a, b: string): string;
var
  before, after :string;
begin
  Result := b;
  if 0 < Pos(a,b) then begin
    before := Copy(b,1,Pos(a,b)-Length(a));
    after := Copy(b,Pos(a,b)+Length(a),Length(b));
    Result := before + after;
    Result := RemoveAllAFromB(a,Result);  //recursive
  end;
end;

и в C я пишу это:

char *s1, *s2, *result; /* original strings and the result string */
int len1, len2; /* lengths of the strings */
for (i = 0; i < len1; i++) {
   for (j = 0; j < len2; j++) {
     if (s1[i] == s2[j]) {
       break;
     }
   }
   if (j == len2) {  /* s1[i] is not found in s2 */
     *result = s1[i]; 
     result++; /* assuming your result array is long enough */
   }
}

, Но сколько оптимизации находится там в версии C? Мы принимаем много о решениях о реализации, что я не думаю о в версии Дельфи. Как строка реализована? В Дельфи я не вижу его. В C я решил, что это будет указатель на массив целых чисел ASCII, которые мы называем символами. В C мы тестируем на символьное существование по одному. В Дельфи я использую Pos

, И это - просто небольшой пример. В большой программе программист C должен сделать эти виды из решений низкого уровня с каждыми несколькими строками кода. Это составляет в целом оптимизированный рукой исполняемый файл ручной работы.

73
ответ дан Community 23 November 2019 в 04:59
поделиться

Существует компромисс, который сделали разработчики C. То есть они приняли решение поместить скорость выше безопасности. C не будет

  • границы индекса массива Проверки
  • Проверка на значения неинициализированной переменной
  • Проверка на утечки памяти
  • , Проверка на нулевого указателя разыменовывает

, Когда Вы индексируете в массив, в Java требуется некоторый вызов метода в виртуальной машине, связанной проверке и других проверках работоспособности. То, что допустимо и абсолютно прекрасный , потому что это добавляет безопасность, где это должно. Но в C, даже довольно тривиальные вещи не помещаются в безопасность. Например, C не требует, чтобы memcpy проверил ли регионы для копирования перекрытия. Это не разработано как язык для программирования приложения большого бизнеса.

, Но эти проектные решения не ошибки на языке C . Они дизайном, поскольку он позволяет компиляторам и писателям библиотеки вытаскивать каждый бит производительности из компьютера. Вот дух C, как документ Объяснения C объясняет его:

код C может быть непортативным. , Хотя это стремилось дать программистам возможность записать действительно портативные программы, Комитет не хотел принуждать программистов к записи портативно, устранять использование C как ''высокоуровневый ассемблер'': способность записать определенный для машины код является одними из преимуществ C.

Сохраняют дух C. Комитет оставался как главная цель сохранить традиционный дух C. Существует много фасетов духа C, но сущность является чувством сообщества базовых принципов, на которых базируется язык C. Некоторые фасеты духа C могут быть получены в итоге во фразах как [1 118]

  • Доверие программист.
  • не препятствуют тому, чтобы программист делал что потребности быть сделанным.
  • Сохраняют язык маленьким и простым.
  • Обеспечивают только один способ сделать операцию.
  • Делают его быстро, даже если это, как гарантируют, не будет портативно.

последней пословице нужно немного объяснения. Потенциал для эффективной генерации кода является одними из самых важных преимуществ C. Чтобы помочь гарантировать, что никакой взрыв кода не происходит, для того, какой, кажется, очень простая операция, много операций определяются, чтобы быть, как аппаратные средства целевой машины делают это, а не по общему абстрактному правилу. Пример этой готовности жить с тем, что машина действительно видна в правилах, которые управляют расширением символьных объектов для использования в выражениях: расширяются ли значения символьных объектов к или неподписанным количествам со знаком, обычно зависит, на котором операция байта более эффективна на целевой машине.

87
ответ дан Arnav Borborah 23 November 2019 в 04:59
поделиться

Многие из этих ответов дают веские причины, почему C является или нет быстрее (в целом или в конкретных сценариях). Несомненно, что:

  • Многие другие языки предоставляют автоматические функции, которые мы считаем само собой разумеющимся. Например, проверка границ, проверка типов во время выполнения и автоматическое управление памятью не предоставляются бесплатно. С этими функциями связаны по крайней мере некоторые затраты, о которых мы можем не думать - или даже не осознавать - при написании кода, использующего эти функции.
  • Шаг от источника к машине часто не такой прямой. на других языках, как в C.
  • OTOH, сказать, что скомпилированный код C выполняется быстрее, чем другой код, написанный на других языках, является обобщением, которое не является т всегда правда. Контрпримеры легко найти (или придумать).

Несмотря на все это, я заметил кое-что еще, что, как мне кажется, влияет на сравнительную производительность C по сравнению со многими другими языками больше, чем любой другой фактор. А именно:

Другие языки часто упрощают написание кода, который выполняется медленнее. Часто это даже поощряется философией дизайна языка. Следствие: программист на C с большей вероятностью напишет код, который не выполняет ненужных операций.

В качестве примера рассмотрим простую программу Windows, в которой создается одно главное окно. Версия AC будет заполнять структуру 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, и добавляет некоторые вещи, которые мы не учитываются, например, проверка ошибок. Более богатая и полная библиотека (по сравнению с теми, которые используются в типичном проекте 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 framework допускает многократное повторение выполнения, чего часто удается избежать с помощью процедурного подхода.

Я не пытаюсь выбирать на C # или .NET framework. Я также не говорю, что модуляризация, обобщение, функции библиотеки / языка, ООП и т. Д. - это плохие вещи . Раньше я делал большую часть своей разработки на C, позже на C ++ и в последнее время на C #. Точно так же до C я использовал в основном сборку. И с каждым шагом «выше» мой язык, я пишу лучшие, более удобные в обслуживании, более надежные программы за меньшее время. Однако они, как правило, действуют немного медленнее.

поддается частому повторению выполнения, чего часто избегают процедурный подход.

Я не пытаюсь выбирать C # или платформу .NET. Я также не говорю, что модуляризация, обобщение, функции библиотеки / языка, ООП и т. Д. - это плохие вещи . Раньше я делал большую часть своей разработки на C, позже на C ++ и в последнее время на C #. Точно так же до C я использовал в основном сборку. И с каждым шагом «выше» мой язык, я пишу лучшие, более удобные в обслуживании, более надежные программы за меньшее время. Однако они, как правило, действуют немного медленнее.

поддается частому повторению выполнения, чего часто избегают процедурный подход.

Я не пытаюсь выбирать C # или платформу .NET. Я также не говорю, что модуляризация, обобщение, функции библиотеки / языка, ООП и т. Д. - это плохие вещи . Раньше я делал большую часть своей разработки на C, позже на C ++ и в последнее время на C #. Точно так же до C я использовал в основном сборку. И с каждым шагом «выше» мой язык, я пишу лучшие, более удобные в обслуживании, более надежные программы за меньшее время. Однако они, как правило, действуют немного медленнее.

позже в C ++ и в последнее время в C #. Точно так же до C я использовал в основном сборку. И с каждым шагом «выше» мой язык, я пишу лучшие, более удобные в обслуживании, более надежные программы за меньшее время. Однако они, как правило, действуют немного медленнее.

позже в C ++ и в последнее время в C #. Точно так же до C я использовал в основном сборку. И с каждым шагом «выше» мой язык, я пишу лучшие, более удобные в обслуживании, более надежные программы за меньшее время. Однако они, как правило, действуют немного медленнее.

6
ответ дан 23 November 2019 в 04:59
поделиться

Просто шаг через машинный код в Вашем IDE, и Вы будете видеть, почему это быстрее (если это быстрее). Это не учитывает большое содержание руки. Возможностями является Ваш Cxx, может также быть сказан пропустить его также, в этом случае это должно быть о том же.

оптимизация Компилятора переоценена, как почти все восприятие о скорости языка.

Оптимизация сгенерированного кода только имеет значение в коде горячей точки, то есть, трудные алгоритмы, лишенные вызовов функции (явный или неявный). Где-либо еще это достигает очень мало.

0
ответ дан Mike Dunlavey 23 November 2019 в 04:59
поделиться

Существует много причин, включая:

  • Это не Объектно-ориентировано.
  • Это компилирует в блок.
  • Это со статическим контролем типов.
  • необходимо сделать управление памятью все собой.
  • Никакая обработка ошибок.
  • Много языков программирования добавляют новые опции. Часть философии C (которому несколько противоречил C++) должна сохранить вещи простыми вместо того, чтобы добавить больше; возьмите не больше, чем, Вам нужно.
0
ответ дан 23 November 2019 в 04:59
поделиться

На самом деле, в некоторых приложениях (числовых) даже C может быть лучше, и я имею в виду не ассемблер, а старый, часто высмеиваемый Fortran. Причина в том, что Fortran гарантирует отсутствие псевдонимов указателей.

0
ответ дан 23 November 2019 в 04:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: