При прослушивании подкаста StackOverflow продолжает появляться джеб, который «настоящие программисты» пишут на C, и что C намного быстрее, потому что он «близок к машине». Оставляя прежнее утверждение для другого поста, что особенного в C, что позволяет ему работать быстрее, чем в других языках? Или, другими словами, что мешает другим языкам компилироваться в двоичный файл, который работает так же быстро, как C?
c
performance
Майк С.
источник
источник
Ответы:
В C. нет ничего особенного. Это одна из причин, почему это быстро.
Новые языки, которые поддерживают сборку мусора , динамическую типизацию и другие возможности, которые облегчают программисту написание программ.
Суть в том, что есть дополнительные накладные расходы на обработку, которые снижают производительность приложения. C не имеет ничего такого, что означает, что нет никаких накладных расходов, но это означает, что программист должен иметь возможность выделять память и освобождать ее, чтобы предотвратить утечки памяти , и должен иметь дело со статической типизацией переменных.
Тем не менее, многие языки и платформы, такие как Java (с его виртуальной машиной Java ) и .NET (с общей средой исполнения языка), с годами улучшили производительность благодаря таким нововведениям, как своевременная компиляция, которая генерирует машинный код из байт-код для достижения более высокой производительности.
источник
Есть компромисс между дизайнерами C. То есть они приняли решение поставить скорость выше безопасности. С не будет
Когда вы индексируете в массив, в Java он требует некоторого вызова метода в виртуальной машине, проверки привязки и других проверок работоспособности. Это действительно и абсолютно хорошо , потому что это добавляет безопасность, где это необходимо. Но в Си даже довольно тривиальные вещи не в безопасности. Например, C не требует, чтобы memcpy проверял, перекрываются ли копируемые регионы. Он не предназначен для программирования большого бизнес-приложения.
Но эти дизайнерские решения не являются ошибками в языке Си . Они разработаны специально, так как позволяют компиляторам и авторам библиотек получать максимальную производительность от компьютера. Вот дух C, как это объясняется в документе C Rationale :
источник
Если вы потратите месяц на создание чего-то в C, который будет работать за 0,05 секунды, а я потрачу целый день на то, чтобы написать то же самое на Java, и это будет выполняться за 0,10 секунды, то действительно ли C быстрее?
Но чтобы ответить на ваш вопрос, хорошо написанный код C будет, как правило, работать быстрее, чем хорошо написанный код на других языках, потому что часть написания хорошего кода C включает в себя выполнение ручной оптимизации на уровне, близком к машинному.
Хотя компиляторы действительно очень умны, они еще не способны творчески придумать код, который конкурирует с алгоритмами с ручным массажем (при условии, что «руки» принадлежат хорошему программисту на Си).
Редактировать:
Множество комментариев напоминает: «Я пишу на C и не думаю об оптимизации».
Но взять конкретный пример из этого поста :
В Delphi я мог бы написать это:
и в CI напишите это:
Но сколько оптимизаций в версии C? Мы принимаем много решений о реализации, о которых я не думаю в версии Delphi. Как реализована строка? В Delphi я этого не вижу. В Си я решил, что это будет указатель на массив целых чисел ASCII, который мы называем символами. В C мы проверяем существование персонажа по одному. В Delphi я использую Pos.
И это только маленький пример. В большой программе программист на С должен принимать подобные низкоуровневые решения с каждыми несколькими строками кода. Он дополняет созданный вручную исполняемый файл, оптимизированный вручную.
источник
Я не видел его уже, так что я скажу это: C , как правило, быстрее , потому что почти все остальное написано в C .
Java построен на C, Python построен на C (или Java, или .NET и т. Д.), Perl и т. Д. ОС написана на C, виртуальные машины написаны на C, компиляторы написаны на C, Интерпретаторы написаны на C. Некоторые вещи все еще написаны на ассемблере, что, как правило, происходит еще быстрее. Все больше и больше вещей пишется во что-то еще, что само написано на C.
Каждый оператор, который вы пишете на других языках (не на ассемблере), обычно реализуется в виде нескольких операторов на C, которые компилируются в собственный машинный код. Поскольку эти другие языки, как правило, существуют для получения более высокого уровня абстракции, чем C, эти дополнительные операторы, требуемые в C, как правило, направлены на повышение безопасности, сложности и обеспечение обработки ошибок. Это часто хорошие вещи, но у них есть цена , и ее имена - скорость и размер .
Лично я написал буквально на десятках языков, охватывающих большую часть доступного спектра, и я лично искал магию, на которую вы намекаете:
После нескольких лет исследований мой ответ - Python (на C). Возможно, вы захотите взглянуть на это. Кстати, вы также можете перейти в Assembly из Python (с небольшой помощью специальной библиотеки).
С другой стороны, плохой код может быть написан на любом языке . Поэтому код C (или ассемблер) не будет автоматически быстрее. Аналогичным образом, некоторые приемы оптимизации могут привести части кода более высокого уровня к языку, близкому к уровню производительности исходного языка C. Но для большинства приложений ваша программа проводит большую часть времени в ожидании на людях или оборудовании, поэтому разница действительно не имеет значения.
Наслаждаться.
источник
Там много вопросов - в основном те, на которые я не могу ответить. Но для этого последнего:
Одним словом, Абстракция.
C - это только один или два уровня абстракции от машинного языка. Языки Java и .Net находятся как минимум на 3 уровнях абстракции от ассемблера. Я не уверен насчет Python и Ruby.
Как правило, чем больше программист играет (сложные типы данных и т. Д.), Тем дальше вы переходите от машинного языка и тем больше требуется перевода.
Я здесь и там, но это основной смысл.
Обновление ------- Есть несколько хороших комментариев к этому сообщению с более подробной информацией.
источник
Дело не в том, что C быстр, а в том, что модель затрат C прозрачна . Если программа на C медленная, она медленная очевидным способом: путем выполнения большого количества операторов. По сравнению со стоимостью операций в C операции высокого уровня над объектами (особенно отражением) или строками могут иметь затраты, которые не очевидны.
Два языка, которые обычно компилируются в двоичные файлы, которые так же быстры, как C, - это Standard ML (с использованием компилятора MLton ) и Objective Caml . Если вы посмотрите игру с тестами, то обнаружите, что для некоторых тестов, таких как бинарные деревья, версия OCaml быстрее, чем C. (Я не нашел записей MLton.) Но не принимайте перестрелку слишком серьезно; это, как говорится, игра, результаты которой часто отражают то, сколько усилий люди приложили для настройки кода.
источник
С не всегда быстрее.
C медленнее, чем, например, Modern Fortran.
C часто медленнее, чем Java для некоторых вещей. (Особенно после того, как JIT-компилятор попробовал ваш код)
C допускает псевдонимы указателей, что означает, что некоторые хорошие оптимизации невозможны. В частности, когда у вас есть несколько исполнительных блоков, это приводит к остановке выборки данных. Вл.
Предположение о том, что арифметическая работа с указателями действительно вызывает медленную раздутую производительность на некоторых семействах процессоров (особенно PIC!). Она использовалась для того, чтобы сосать большую на сегментированной x86.
По сути, когда вы получаете векторный модуль или распараллеливающий компилятор, C воняет, и современный Fortran работает быстрее.
Уловки программиста на C, такие как thunking (изменение исполняемого файла на лету), приводят к остановке предварительной загрузки ЦП.
Вы получаете дрейф?
И наш хороший друг, x86, выполняет набор инструкций, которые в наши дни мало связаны с реальной архитектурой процессора. Теневые регистры, оптимизаторы загрузки-хранения, все в процессоре. Так что С тогда близок к виртуальному металлу. Настоящий металл, Intel не дает тебе увидеть. (Исторически процессоры VLIW были чем-то вроде бюста, так что, может быть, это не так уж и плохо.)
Если вы программируете на C на высокопроизводительном DSP (может быть, TI DSP?), Компилятор должен сделать некоторые хитрые вещи, чтобы развернуть C на нескольких параллельных исполнительных блоках. Таким образом, в этом случае C не близок к металлу, но близок к компилятору, который будет выполнять оптимизацию всей программы. Weird.
И, наконец, некоторые процессоры (www.ajile.com) выполняют аппаратные байт-коды Java. C будет PITA для использования на этом процессоре.
источник
Ничего. Современные языки, такие как Java или .NET, больше ориентированы на производительность труда программиста, чем на производительность. Оборудование дешевое в наши дни. Также компиляция в промежуточное представление дает много бонусов, таких как безопасность, переносимость и т. Д. .NET CLR может использовать преимущества другого оборудования - например, вам не нужно вручную оптимизировать / перекомпилировать программу, чтобы использовать набор инструкций SSE.
источник
Основными факторами являются то, что это статически типизированный язык, который компилируется в машинный код. Кроме того, поскольку это язык низкого уровня, он, как правило, не делает ничего, о чем вы ему не говорите.
Это некоторые другие факторы, которые приходят на ум.
Большинство языков статической типизации могут быть скомпилированы так же быстро или быстрее, чем C, тем не менее, особенно если они могут делать предположения, которые C не может сделать из-за наложения указателей и т. Д.
источник
Я думаю, вы забыли, что ассемблер также является языком :)
А если серьезно, программы на C быстрее, только когда программист знает, что он делает. Вы можете легко написать программу на C, которая работает медленнее, чем программы, написанные на других языках, которые выполняют ту же работу.
Причина, по которой C быстрее, заключается в том, что он спроектирован таким образом. Это позволяет вам делать много вещей «более низкого уровня», которые помогают компилятору оптимизировать код. Или, скажем так, вы, программист, несете ответственность за оптимизацию кода. Но это часто довольно сложно и подвержено ошибкам.
Другие языки, как и другие уже упомянутые, больше ориентированы на производительность программиста. Принято считать, что время программиста намного дороже, чем машинное время (даже в старые времена). Поэтому имеет смысл минимизировать время, которое программисты тратят на написание и отладку программ, а не на время их выполнения. Чтобы сделать это, вы пожертвуете тем, что можете сделать, чтобы программа стала быстрее, потому что многое автоматизировано.
источник
По большей части каждая инструкция на C соответствует очень немногим инструкциям на ассемблере. По сути, вы пишете машинный код более высокого уровня, поэтому вы можете контролировать практически все, что делает процессор. Многие другие скомпилированные языки, такие как C ++, содержат много простых инструкций, которые могут превратить в код гораздо больше, чем вы думаете (виртуальные функции, конструкторы копирования и т. Д.). И интерпретируемые языки, такие как Java или Ruby, имеют еще один уровень: инструкции, которые вы никогда не увидите - виртуальная машина или интерпретатор.
источник
Я знаю, что многие люди говорили это многословно, но:
источник
C ++ в среднем быстрее (как это было изначально, в основном это расширенный набор C, хотя есть некоторые различия). Однако для конкретных тестов часто есть другой язык, который работает быстрее.
https://benchmarksgame-team.pages.debian.net/benchmarksgame/
fannjuch-redux
был самым быстрым в Скалеn-body
иfasta
были быстрее в Аде.spectral-norm
был самым быстрым в Фортране.reverse-complement
,mandelbrot
Иpidigits
были самым быстрым в САР.regex-dna
был самым быстрым в JavaScript.chameneou-redux
была самая быстрая Java 7.thread-ring
был самым быстрым в Haskell.Остальные тесты были самыми быстрыми в C или C ++.
источник
extern "C"
не имеет ничего общего с C ++, являющимся надмножеством C.system("bash script.sh");
работает для любого скрипта bash, и, следовательно, C является надмножеством bash.extern "C"
обеспечивает связь C в C ++ из-за искажения имени. Принимая во внимание, что вызов X как расширенного набора Y означает, что все, что может быть сделано в Y, также может быть сделано в X, что не относится к C ++. Существует довольно много языковых конструкций, которые допустимы в C, но не в C ++.bash
бы доступную программу командной строки. Если бы он сделал и включил, какую версию / спецификацию bash нужно было поддерживать, я бы посчитал это надмножеством.struct foo { int: this; }; typedef float foo;
Многие из этих ответов дают веские причины того, почему C быстрее или нет (в целом или в определенных сценариях). Это бесспорно, что:
Несмотря на все это, есть кое-что еще, что я заметил, что, как мне кажется, влияет на сравнительную производительность языка C по сравнению со многими другими языками в большей степени, чем любой другой фактор. Для остроумия:
Другие языки часто облегчают написание кода, который выполняется медленнее. Часто это даже поощряется философией дизайна языка. Следствие: программист на C с большей вероятностью будет писать код, который не выполняет ненужных операций.
В качестве примера рассмотрим простую программу Windows, в которой создается одно главное окно. Версия AC будет заполнять
WNDCLASS[EX]
структуру, которая будет переданаRegisterClass[Ex]
, затем вызыватьCreateWindow[Ex]
и вводить цикл сообщений. Ниже приведен очень упрощенный и сокращенный код:Эквивалентная программа на C # может быть всего одной строкой кода:
Эта единственная строка кода предоставляет все функциональные возможности, которые сделали почти 20 строк кода на C, и добавляет некоторые вещи, которые мы пропустили, такие как проверка ошибок. Более богатая и полная библиотека (по сравнению с библиотеками, используемыми в типичном C-проекте) проделала большую работу для нас, освободив наше время для написания еще большего количества фрагментов кода, которые нам не хватает, но требуют много шагов за кулисами.
Но богатая библиотека, обеспечивающая легкое и быстрое раздувание кода, на самом деле не моя точка зрения. Моя точка зрения становится более очевидной, когда вы начинаете изучать, что на самом деле происходит, когда наша маленькая однострочная строка действительно выполняется. Для развлечения иногда включите доступ к исходным кодам .NET в Visual Studio 2008 или более поздней версии и перейдите к простой строчке выше. Одна из забавных маленьких жемчужин, с которыми вы столкнетесь, - это комментарий в получателе
Control.CreateParams
:Десять раз . Информация, приблизительно эквивалентная сумме того, что хранится в
WNDCLASSEX
структуре и того, что передано,CreateWindowEx
извлекается изControl
класса десять раз, прежде чем она сохраняется вWNDCLASSEX
структуре и передается вRegisterClassEx
иCreateWindowEx
.В общем, количество инструкций, выполняемых для выполнения этой основной задачи, на 2–3 порядка больше в C #, чем в C. Отчасти это связано с использованием многофункциональной библиотеки, которая обязательно обобщается по сравнению с наш простой C-код, который делает именно то, что нам нужно, и ничего более. Но отчасти это связано с тем, что модульная, объектно-ориентированная природа .NET Framework поддается многократному повторению выполнения, которого часто избегает процедурный подход.
Я не пытаюсь выбрать на C # или .NET Framework. Также я не говорю, что модульность, обобщение, функции библиотеки / языка, ООП и т. Д. - это плохие вещи . Я делал большую часть своей разработки на C, позже на C ++, а в последнее время на C #. Точно так же до C я использовал в основном сборку. И с каждым шагом "выше" мой язык, я пишу лучше, более удобные в обслуживании, более надежные программы за меньшее время. Они, однако, имеют тенденцию исполняться немного медленнее.
источник
Я не думаю, что кто-то упомянул тот факт, что в компиляторы C вложено гораздо больше усилий, чем в любой другой компилятор, возможно, за исключением Java.
C чрезвычайно оптимизирован по многим причинам, о которых уже говорилось - больше, чем почти любой другой язык. Так что, если такое же количество усилий будет вложено в другие языковые компиляторы, С, вероятно, все равно выйдет на первое место.
Я думаю, что есть, по крайней мере, один язык-кандидат, который с усилием мог бы быть оптимизирован лучше, чем C, и, таким образом, мы могли видеть реализации, которые производят более быстрые двоичные файлы. Я думаю о digital mars D, потому что создатель позаботился о создании языка, который потенциально мог бы быть лучше оптимизирован, чем C. Возможно, есть другие языки, которые имеют такую возможность. Однако я не могу себе представить, что любой язык будет иметь компиляторы более чем на несколько процентов быстрее, чем лучшие компиляторы Си. Я хотел бы быть неправым.
Я думаю, что настоящий «низко висящий фрукт» будет на языках, которые разработаны для людей, чтобы их было легко оптимизировать. Опытный программист может заставить любой язык работать быстрее, но иногда вам приходится делать смешные вещи или использовать неестественные конструкции, чтобы это произошло. Хотя это всегда требует усилий, хороший язык должен генерировать относительно быстрый код, не заботясь о том, как именно написана программа.
Также важно (по крайней мере для меня), что код наихудшего случая имеет тенденцию быть быстрым. В Интернете есть множество «доказательств», что Java работает быстрее или быстрее, чем C, но это основано на примерах выбора вишни. Я не большой поклонник C, но я знаю, что НИЧЕГО, что я пишу на C, будет работать хорошо. С Java он «вероятно» будет работать в пределах 15% от скорости, обычно в пределах 25%, но в некоторых случаях это может быть намного хуже. Любые случаи, когда это происходит так же быстро или в пределах нескольких процентов, обычно связаны с тем, что большая часть времени затрачивается на библиотечный код, который в любом случае сильно оптимизирован.
источник
Это на самом деле немного увековеченной лжи. Хотя это правда, что программы на C часто бывают быстрее, это не всегда так, особенно если программист на С не очень хорош в этом.
Одна большая вопиющая дыра, о которой люди обычно забывают, - это когда программе приходится блокировать какие-то операции ввода-вывода, например ввод пользователя в любой программе с графическим интерфейсом. В этих случаях не имеет значения, какой язык вы используете, поскольку вы ограничены скоростью, с которой данные могут поступать, а не тем, насколько быстро вы можете их обработать. В этом случае не имеет большого значения, используете ли вы C, Java, C # или даже Perl; вы просто не можете идти быстрее, чем могут поступить данные.
Другая важная вещь заключается в том, что использование сборки мусора и отсутствие правильных указателей позволяет виртуальной машине выполнять ряд оптимизаций, недоступных на других языках. Например, JVM способна перемещать объекты в куче для ее дефрагментации. Это значительно ускоряет распределение в будущем, поскольку следующий индекс можно просто использовать, а не искать его в таблице. Современные JVM также не должны фактически освобождать память; вместо этого они просто перемещают живые объекты вокруг, когда они собирают, и израсходованная память из мертвых объектов восстанавливается практически бесплатно.
Это также поднимает интересный вопрос о C и тем более о C ++. Есть что-то вроде философии дизайна: «Если тебе это не нужно, ты не платишь за это». Проблема в том, что, если вы этого хотите, вы платите за это через нос. Например, реализация vtable в Java имеет тенденцию быть намного лучше, чем реализации C ++, поэтому вызовы виртуальных функций намного быстрее. С другой стороны, у вас нет выбора, кроме как использовать виртуальные функции в Java, и они все еще стоят чего-то, но в программах, которые используют много виртуальных функций, сниженная стоимость складывается.
источник
Дело не столько в языке, сколько в инструментах и библиотеках. Доступные библиотеки и компиляторы для C намного старше, чем для более новых языков. Вы можете подумать, что это замедлит их, но наоборот.
Эти библиотеки были написаны в то время, когда вычислительная мощность и память были на высоте. Они должны были быть написаны очень эффективно, чтобы вообще работать. Разработчикам компиляторов Си также пришлось долго работать над всевозможными умными оптимизациями для разных процессоров. Зрелость и широкое распространение C делает его значительным преимуществом перед другими языками того же возраста. Это также дает С преимущество в скорости перед более новыми инструментами, которые не подчеркивают необработанную производительность так, как С.
источник
Отсутствие абстракции делает C быстрее. Если вы напишите выходное утверждение, вы точно знаете, что происходит. Если вы напишите выходной оператор в java, он будет скомпилирован в файл класса, который затем будет запущен на виртуальной машине с введением уровня абстракции. Отсутствие объектно-ориентированных функций как части языка также увеличивает его скорость и уменьшает количество генерируемого кода. Если вы используете C в качестве объектно-ориентированного языка, тогда вы делаете все кодирование для таких вещей, как классы, унаследование и т. Д. Это означает, вместо того, чтобы сделать что-то достаточно обобщенное для всех с объемом кода и оценкой производительности, которая требует только написания что вам нужно, чтобы сделать работу.
источник
Удивительно видеть, что старый «C / C ++ должен быть быстрее, чем Java, потому что Java интерпретируется», миф все еще жив и развязан. Есть статьи, выпущенные несколько лет назад , а также более свежие , которые объясняют концепциями или измерениями, почему это не всегда так .
Текущие реализации виртуальных машин (и, между прочим, не только JVM) могут использовать информацию, собранную во время выполнения программы, для динамической настройки кода во время работы с использованием различных методов:
и множество других настроек, основанных на знании того, что на самом деле делает код, и на реальных характеристиках среды, в которой он работает.
источник
Самый быстрый работающий код - это тщательно созданный вручную машинный код. Ассемблер будет почти таким же хорошим. Оба очень низкого уровня, и для написания кода требуется много кода. С немного выше ассемблера. У вас все еще есть возможность контролировать вещи на очень низком уровне в реальной машине, но есть достаточно абстракции, чтобы писать ее быстрее и проще, чем на ассемблере. Другие языки, такие как C # и JAVA, еще более абстрактны. В то время как Ассемблер и машинный код называются языками низкого уровня, C # и JAVA (и многие другие) называются языками высокого уровня. С иногда называют языком среднего уровня.
источник
Не верьте кому-то на слово, посмотрите на дизассемблирование C и вашего языка в любой важной части вашего кода. Я думаю, что вы можете просто посмотреть в окне разборки во время выполнения в Visual Studio, чтобы увидеть разобранный .Net. Это должно быть возможно, если сложно использовать Java с помощью windbg, хотя, если вы делаете это с .Net, многие проблемы будут одинаковыми.
Я не люблю писать на C, если мне это не нужно, но я думаю, что многие из утверждений, высказанных в этих ответах, которые говорят о скорости языков, отличных от C, можно отложить, просто разобрав ту же самую подпрограмму в C и на выбранном вами языке более высокого уровня, особенно если используется большое количество данных, как это обычно происходит в приложениях, критичных к производительности. Фортран может быть исключением в своей области, не знаю. Это более высокий уровень, чем С?
В первый раз я сравнил код JIT с собственным кодом и решил все без исключения вопросы, может ли код .Net работать сравнимо с кодом C. Дополнительный уровень абстракции и все проверки безопасности сопряжены со значительными затратами. Те же затраты могут быть применимы и к Java, но не поверьте мне на слово, попробуйте что-нибудь, где производительность критична. (Кто-нибудь знает достаточно о JITed Java, чтобы найти скомпилированную процедуру в памяти? Это, безусловно, должно быть возможно)
источник
1) Как уже говорили другие, С делает для вас меньше. Нет инициализирующих переменных, нет проверки границ массива, нет управления памятью и т. Д. Эти функции в других языках стоят памяти и циклов ЦП, которые C не тратит.
2) Ответы о том, что C менее абстрактен и, следовательно, быстрее, только наполовину правильны, я думаю. Технически говоря, если у вас был «достаточно продвинутый компилятор» для языка X, то язык X мог бы приближаться или равняться скорости C. Разница с C состоит в том, что, поскольку он отображается так очевидно (если вы прошли курс архитектуры), и непосредственно на ассемблере, что даже наивный компилятор может сделать достойную работу. Для чего-то вроде Python вам нужен очень продвинутый компилятор, чтобы предсказывать вероятные типы объектов и генерировать машинный код на лету - семантика C достаточно проста, чтобы простой компилятор мог преуспеть.
источник
В старые добрые времена было только два типа языков: скомпилированный и интерпретированный.
Скомпилированные языки используют «компилятор», чтобы прочитать синтаксис языка и преобразовать его в идентичный код на ассемблере, который может быть непосредственно на процессоре. Интерпретируемые языки использовали несколько различных схем, но по сути синтаксис языка был преобразован в промежуточную форму, а затем запущен в «интерпретаторе», среде для выполнения кода.
Таким образом, в некотором смысле был еще один «слой» - интерпретатор - между кодом и машиной. И, как всегда в случае с компьютером, чем больше ресурсов, тем больше ресурсов используется. Переводчики были медленнее, потому что им приходилось выполнять больше операций.
Совсем недавно мы видели больше гибридных языков, таких как Java, в которых для их работы используются как компилятор, так и интерпретатор. Это сложно, но JVM быстрее, более изощренна и более оптимизирована, чем старые интерпретаторы, поэтому она значительно лучше выполняет (со временем) ближе к просто скомпилированному коду. Конечно, у новых компиляторов также есть более хитроумные приемы оптимизации, поэтому они, как правило, генерируют код лучше, чем раньше. Но большинство оптимизаций, чаще всего (хотя и не всегда), делают некоторый тип компромисса таким, что они не всегда быстрее при любых обстоятельствах. Как и все остальное, ничего не приходит бесплатно, поэтому оптимизаторы должны получить что-то свое (хотя зачастую это использует процессор времени компиляции для экономии времени выполнения).
Возвращаясь к C, это простой язык, который можно скомпилировать в довольно оптимизированную сборку и затем запустить непосредственно на целевой машине. В C, если вы увеличиваете целое число, более чем вероятно, что это всего лишь один шаг ассемблера в CPU, в Java, однако, это может оказаться намного больше (и может также включать в себя сборку мусора: -) C предлагает вам абстракцию, которая находится ближе к машине (ассемблер - ближайший), но вам в конечном итоге придется проделать гораздо больше работы, чтобы запустить ее, и она не так защищена, проста в использовании или не допускает ошибок. Большинство других языков дают вам более высокую абстракцию и заботятся о большем количестве базовых деталей для вас, но в обмен на их расширенную функциональность им требуется больше ресурсов для работы. Когда вы обобщаете некоторые решения, вам приходится работать с более широким спектром вычислений,
Павел.
источник
++i
может скомпилировать в «add [ebp - 8], 1». Нельзя сказать, что выборка, приращение, сохранение по-прежнему не происходит, но об этом заботится процессор, и, как сказал Пол, это всего лишь одна инструкция.Если оставить в стороне передовые методы оптимизации, такие как оптимизация « горячих точек» , предварительно скомпилированные мета-алгоритмы и различные формы параллелизма , фундаментальная скорость языка сильно коррелирует с неявной закулисной сложностью, необходимой для поддержки операций, которые обычно быть указанным во внутренних циклах .
Возможно, наиболее очевидным является проверка достоверности косвенных ссылок в памяти, например, проверка указателей
null
и проверка индексов по границам массивов. Большинство языков высокого уровня выполняют эти проверки неявно, а C - нет. Однако это не обязательно является фундаментальным ограничением этих других языков - достаточно умный компилятор может быть способен удалить эти проверки из внутренних циклов алгоритма посредством некоторой формы движения кода, инвариантного к циклу .Более фундаментальным преимуществом C (и в аналогичной степени тесно связанный C ++) является сильная зависимость от выделения памяти на основе стека , которая по своей природе является быстрой для выделения, освобождения и доступа. В C (и C ++) первичный стек вызовов может использоваться для выделения примитивов, массивов и агрегатов (
struct
/class
).Хотя C действительно предоставляет возможность динамически распределять память произвольного размера и времени жизни (используя так называемую «кучу»), этого по умолчанию избегают (вместо этого используется стек).
К счастью, иногда можно тиражировать стратегию выделения памяти C в средах выполнения других языков программирования. Это было продемонстрировано в asm.js , который позволяет переводить код, написанный на C или C ++, в подмножество JavaScript и безопасно выполнять его в среде веб-браузера - с почти естественной скоростью.
Кроме того, еще одна область, где C и C ++ затмевают большинство других языков по скорости, - это возможность бесшовной интеграции с собственными наборами машинных команд. Ярким примером этого является (зависящий от компилятора и платформы) доступность встроенных функций SIMD, которые поддерживают создание пользовательских алгоритмов, использующих преимущества практически повсеместно распространенного оборудования для параллельной обработки, при этом все еще используя абстракции распределения данных, предоставляемые языком (ниже). распределение уровней на уровне управляется компилятором).
источник
Я нашел ответ на ссылку о том, почему некоторые языки быстрее, а некоторые медленнее. Надеюсь, это прояснит, почему C или C ++ быстрее других. Есть и другие языки, которые быстрее C, но мы не можем использовать их все. Некоторое объяснение -
Одна из главных причин того, что Фортран остается важным, заключается в том, что он быстрый: процедуры вычисления чисел, написанные на Фортране, как правило, быстрее, чем эквивалентные процедуры, написанные на большинстве других языков. Языки, которые конкурируют с Fortran в этом пространстве - C и C ++ - используются, потому что они конкурентоспособны с этой производительностью.
Возникает вопрос: почему? Что в C ++ и Fortran делает их быстрыми и почему они превосходят другие популярные языки, такие как Java или Python?
Интерпретация и компиляция Существует много способов категоризации и определения языков программирования в соответствии со стилем программирования, который они поощряют, и функциями, которые они предлагают. Если смотреть на производительность, самое большое различие заключается в интерпретации и компилировании языков.
Разделить не сложно; скорее есть спектр. С одной стороны, у нас есть традиционные скомпилированные языки, группа, которая включает в себя Fortran, C и C ++. В этих языках существует дискретная стадия компиляции, которая переводит исходный код программы в исполняемую форму, которую процессор может использовать.
Этот процесс компиляции состоит из нескольких этапов. Исходный код анализируется и анализируется. На этом этапе можно обнаружить основные ошибки кодирования, такие как опечатки и орфографические ошибки. Анализируемый код используется для генерации представления в памяти, которое также можно использовать для обнаружения ошибок - на этот раз семантических ошибок, таких как вызов функций, которые не существуют, или попытки выполнения арифметических операций над строками текста.
Это представление в памяти затем используется для управления генератором кода, который создает исполняемый код. Оптимизация кода для повышения производительности сгенерированного кода выполняется в разное время в этом процессе: высокоуровневые оптимизации могут быть выполнены для представления кода, а низкоуровневые оптимизации используются на выходе генератора кода.
На самом деле выполнение кода происходит позже. Весь процесс компиляции просто используется для создания чего-то, что может быть выполнено.
На противоположном конце у нас есть переводчики. Интерпретаторы будут включать в себя этап синтаксического анализа, аналогичный этапу компилятора, но затем он используется для непосредственного выполнения, при этом программа запускается немедленно.
В самом простом интерпретаторе есть исполняемый код, соответствующий различным функциям, поддерживаемым языком, - поэтому он будет иметь функции для добавления чисел, соединения строк и всего, что еще имеет данный язык. Когда он анализирует код, он ищет соответствующую функцию и выполняет ее. Переменные, созданные в программе, будут храниться в некоторой таблице поиска, которая сопоставляет их имена с их данными.
Самый экстремальный пример стиля интерпретатора - это что-то вроде командного файла или сценария оболочки. В этих языках исполняемый код часто даже не встроен в сам интерпретатор, а скорее в отдельные программы.
Так почему же это влияет на производительность? В целом, каждый уровень косвенности снижает производительность. Например, самый быстрый способ сложения двух чисел - это иметь оба этих числа в регистрах процессора и использовать инструкцию сложения процессора. Это то, что могут делать скомпилированные программы; они могут помещать переменные в регистры и использовать инструкции процессора. Но в интерпретируемых программах для этого же сложения может потребоваться два поиска в таблице переменных для извлечения значений, которые необходимо добавить, а затем вызов функции для выполнения сложения. Эта функция вполне может использовать ту же инструкцию процессора, которую использует скомпилированная программа для выполнения фактического сложения, но вся дополнительная работа перед тем, как команда может быть фактически использована, замедляет работу.
Если вы хотите узнать больше, пожалуйста, проверьте источник
источник
Некоторые алгоритмы C ++ быстрее, чем C, а некоторые реализации алгоритмов или шаблонов проектирования в других языках могут быть быстрее, чем C.
Когда люди говорят, что C быстр, а затем переходят к разговору о каком-то другом языке, они обычно используют производительность C в качестве ориентира.
источник
С современными оптимизирующими компиляторами очень маловероятно, что чистая программа на Си будет намного быстрее, чем скомпилированный .net код, если вообще будет. Благодаря повышению производительности, которое предоставляют разработчикам такие среды, как .net, вы можете делать вещи за день, который обычно занимал недели или месяцы в обычном C. В сочетании с более низкой стоимостью аппаратного обеспечения по сравнению с зарплатой разработчика, просто НАПИСАТЬ дешевле материал на высокоуровневом языке и аппаратное выбрасывание на любой скорости.
Причина, по которой Джефф и Джоэл говорят о том, что C является языком «настоящего программиста», заключается в том, что в C. нет ручного удержания. Вы должны выделить свою собственную память, освободить эту память, выполнить собственную проверку границ и т. Д. Нет такой вещи как новый объект (); Здесь нет сборки мусора, классов, ООП, структур сущностей, LINQ, свойств, атрибутов, полей или чего-либо подобного. Вы должны знать такие вещи, как арифметика указателя и как разыменовать указатель. И, в этом отношении, знать и понимать, что такое указатель. Вы должны знать, что такое стековый фрейм и каков указатель инструкции. Вы должны знать модель памяти архитектуры процессора, над которой вы работаете. Существует много неявного понимания архитектуры микрокомпьютера (обычномикрокомпьютер, над которым вы работаете) при программировании на C, которого просто нет и не нужно при программировании на C # или Java. Вся эта информация была выгружена программисту компилятора (или ВМ).
источник
Это разница между автоматическим и ручным, языки более высокого уровня являются абстракциями, таким образом, автоматизированными. C / C ++ управляются и обрабатываются вручную, даже код проверки ошибок иногда является ручным трудом.
C и C ++ также являются скомпилированными языками, что означает, что ни один из них не везде работает, эти языки должны быть точно настроены для аппаратного обеспечения, с которым вы работаете, добавляя тем самым дополнительный уровень сложности. Хотя сейчас это немного ослабевает, поскольку компиляторы C / C ++ становятся все более распространенными на всех платформах. Вы можете делать кросс-компиляции между платформами. Это все еще не везде, где вы работаете, ваш компилятор А инструктирует компилировать против компилятора Б того же кода с другой архитектурой.
Суть языка С не в том, чтобы его было легко понять или обосновать, поэтому его также называют системными языками. Они вышли перед всей этой чепухой высокого уровня абстракции. Это также, почему они не используются для веб-программирования переднего плана. Они просто не подходят для этой задачи, они предназначены для решения сложных проблем, которые не могут быть решены с помощью обычных языковых инструментов.
Вот почему вы получаете сумасшедшие вещи, такие как (микроархитектуры, драйверы, квантовая физика, игры AAA, операционные системы), для которых C и C ++ просто хорошо подходят. Скорость и число хрустят, являющиеся главными областями.
источник
C быстр, потому что это нативно скомпилированный язык низкого уровня. Но С не самый быстрый. В Benchmark Рекурсивных Фибоначчи показывает , что Руст, Crystal и Nim могут быть быстрее.
источник
Есть много причин, в том числе:
источник