C# частично интерпретируется или действительно компилируется?
Об этом много противоречивой информации. В то время как некоторые говорят, что C# компилируется (так как он компилируется в IL, а затем в нативный код при запуске), другие говорят, что он интерпретируется так, как ему нужно.NET. EN Wiki говорит:
Многие интерпретируемые языки сначала компилируются в некую форму кода виртуальной машины, которая затем либо интерпретируется, либо компилируется во время выполнения в собственный код.
Так что я совсем запутался. Может ли кто-нибудь объяснить это ясно?
15 ответов
C# компилируется в IL компилятором C#.
Этот IL затем компилируется точно в срок (JIT) по мере необходимости на родном языке ассемблера хост-машины. Можно было бы написать среду выполнения.NET, которая интерпретировала бы вместо этого IL. Даже если бы это было сделано, я бы до сих пор утверждал, что C# - это скомпилированный язык.
Чисто скомпилированный язык имеет некоторые преимущества. Скорость, как правило, и часто рабочий размер набора. Чисто интерпретированный язык имеет некоторые преимущества. Гибкость, не требующая явной стадии компиляции, которая позволяет нам редактировать на месте, и часто более простая переносимость.
В этом случае смешанный язык вписывается в середину.
Только по этой причине мы можем думать о сопряженном языке как скомпилированном или интерпретированном в зависимости от того, какую позицию по какой метрике мы хотим достичь, и наших предрассудков за и против того или другого.
C# также может быть скомпилирован при первом запуске, как это происходит в ASP.NET, что делает его близким к интерпретируемому в этом случае (хотя он все еще компилируется в IL и затем в этом случае подключается). Конечно, в этом случае он обладает практически всеми преимуществами интерпретации (сравните с VBScript или JScript, используемым в классическом ASP), а также многими преимуществами компилируемого.
Строго говоря, ни один язык не является сопряженным, интерпретируемым или скомпилированным как язык. Мы можем использовать NGen C# для собственного кода (хотя, если он делает что-то вроде динамической загрузки сборки, он все равно будет использовать IL и джиттинг). Мы могли бы написать intepretter для C или C++ (несколько человек сделали это). В своем наиболее распространенном случае использования C# компилируется в IL, который затем соединяется, что не совсем классическое определение интерпретируемого или компилируемого.
Слишком много семантики и высказываний, основанных на мнении.
Во-первых: C# не интерпретируемый язык; CLR и JVM считаются "средами исполнения" или "промежуточным ПО", но одно и то же имя относится к таким вещам, как Perl. Это создает много путаницы среди людей, связанных с именами.
Термин "интерпретатор", ссылающийся на среду выполнения, обычно означает, что существующий код интерпретирует некоторый не родной код. Существует две большие парадигмы: парсинг читает исходный код и выполняет логические действия; Выполнение байт-кода сначала компилирует код в ненативное двоичное представление, для интерпретации которого требуется гораздо меньше циклов ЦП.
Java изначально скомпилирована в байт-код, затем прошла через интерпретатор; теперь JVM читает байт-код и как раз вовремя компилирует его в нативный код. CIL делает то же самое: CLR использует своевременную компиляцию в нативный код.
Рассмотрим все комбинации запуска исходного кода, запуска байт-кода, компиляции в нативную компиляцию, выполняемую точно в срок, запуска исходного кода через компилятор для нативного точного выполнения и так далее. Семантика того, является ли язык компилируемым или интерпретируемым, становится бессмысленной.
В качестве примера: многие интерпретируемые языки используют компиляцию байт-кода точно в срок. C# компилируется в CIL, который JIT компилирует в native; напротив, Perl немедленно компилирует скрипт в байт-код, а затем запускает этот байт-код через интерпретатор. Вы можете запустить сборку C# только в формате байт-кода CIL; Вы можете запустить скрипт Perl только в формате исходного кода.
Компиляторы точно вовремя также запускают много внешних и внутренних контрольно-измерительных приборов. Среда выполнения отслеживает выполнение различных функций, а затем корректирует компоновку кода, чтобы оптимизировать ветви и организацию кода для его конкретного потока выполнения. Это означает, что JIT-код может выполняться быстрее, чем собственный скомпилированный код (как, например, C++ или C#, запускаемый через IL2CPP), потому что JIT корректирует свою стратегию оптимизации в соответствии с фактическим случаем выполнения кода при его запуске.
Добро пожаловать в мир компьютерного программирования. Мы решили сделать это чрезвычайно сложным, а затем добавить неописательные имена ко всему. Цель состоит в том, чтобы создать пламенные войны по определению слов, которые не имеют практического значения.
Если вы чувствуете, узнали или ушли из старой школы, что скомпилированный EXE идет от исходного кода к машинному коду, тогда интерпретируется C#. Если вы думаете, что скомпилированный означает преобразование исходного кода в другой код, такой как байт-код, то да, он преобразован. Для меня все, что требует обработки во время выполнения для работы в ОС, для которой оно было построено, интерпретируется.
Посмотрите здесь: http://msdn.microsoft.com/library/z1zx9t92
Исходный код, написанный на C#, компилируется в промежуточный язык (IL), который соответствует спецификации CLI.
(...)
Когда программа на C# выполняется, сборка загружается в CLR, которая может выполнять различные действия на основе информации в манифесте. Затем, если требования безопасности соблюдены, CLR выполняет компиляцию точно в срок (JIT) для преобразования кода IL в машинные инструкции.
Прежде всего давайте разберемся с определениями интерпретации и компиляции.
"Компилировать" (при обращении к коду) означает переводить код с одного языка на другой. Как правило, из удобочитаемого исходного кода в машинный код, который может обработать целевой процессор.
"Интерпретировать" (при ссылке на код) ТАКЖЕ означает перевод кода с одного языка на другой. Но на этот раз он обычно используется для перехода от удобочитаемого исходного кода к промежуточному коду, который берется виртуальной машиной, которая интерпретирует его в машинный код.
Просто быть чистым
Исходный код -> Компилятор -> Машинный код
Исходный код -> Компилятор -> Байт-код -> Интерпретатор -> Машинный код
Теоретически любой язык может быть интерпретирован или скомпилирован. Обычно Java компилируется в байт-код, который интерпретируется виртуальной машиной Java в машинный код. C# обычно интерпретируется как байт-код, который компилируется CLR, общеязыковой средой выполнения, другой виртуальной машиной.
Безусловно, все это маркетинговый трюк. Термин "интерпретированный" был добавлен (или, по крайней мере, увеличен в использовании), чтобы помочь продемонстрировать, насколько аккуратной была своевременная компиляция. Но они могли просто использовать "скомпилированный". Различие заключается скорее в изучении английского языка и тенденций бизнеса, чем в техническом аспекте.
C# интерпретируется и компилируется при его жизни. C# компилируется в виртуальный язык, который интерпретируется виртуальной машиной.
Путаница проистекает из нечеткой концепции "скомпилированного языка".
"Скомпилированный язык" является неправильным в некотором смысле, потому что скомпилированный или интерпретированный является не свойством языка, а средой выполнения.
Например, вы могли бы написать интерпретатор C, но люди обычно называют его "Скомпилированный язык", потому что реализации C компилируются в машинный код, а язык был разработан с учетом компиляции.
Большинству языков, если не всем, требуется переводчик, который переводит свои сценарии в машинные коды, чтобы процессор мог понять и выполнить его!
Каждый язык обрабатывает перевод по-своему!
Например, "AutoIt" - это то, что мы можем описать как язык, интерпретируемый на 100%!
Зачем?
Потому что интерпретатор "AutoIt" постоянно нужен, пока выполняется его скрипт! Смотрите пример ниже:
Loop, 1000
Any-Code
Интерпретатор "AutoIt" должен будет переводить "Any-Code" 1000 раз в машинный код, что автоматически делает "AutoIt" медленным языком!
С другой стороны, C# по-разному обрабатывает процесс перевода, интерпретатор C# требуется только один раз, перед выполнением сценария, после этого он больше не требуется во время выполнения сценария!
Интерпретатору C# придется переводить "Any-Code" только один раз в машинный код, что автоматически делает "C#" быстрым языком!
Так что в основном,
Язык, который требует своего интерпретатора во время выполнения скрипта, является "Интерпретируемым языком"!
Язык, который требует интерпретатора только один раз (перед выполнением скрипта), является "Скомпилированным языком"!
В заключение,
"AutoIt" - это "Интерпретированный язык"!
"C#" - это "скомпилированный язык"!
Я считаю, что это довольно старая тема.
С моей точки зрения, интерпретируемый код будет проходить через интерпретатор, построчно переводить и исполняться одновременно. Как и пример javascript, это интерпретируемый код, когда в строке javascript возникла ошибка, скрипт просто сломается.
Во время скомпилированного кода он будет проходить через компилятор, переводить весь код сразу в другую форму кода, не выполняя его в первую очередь. Исполнение в другом контексте.
Если мы согласны с определением интерпретатора "В информатике интерпретатор - это компьютерная программа, которая непосредственно выполняет, т.е. выполняет, инструкции, написанные на языке программирования или языке сценариев, не требуя, чтобы они были предварительно скомпилированы в программу на машинном языке."Нет никаких сомнений: C# не является интерпретируемым языком.
C#, как и Java, имеет гибридный языковой процессор. Гибридные процессоры выполняют задачи как интерпретации, так и компиляции.
C# является компилируемым языком.
Вероятно, я повторяю, вероятно, так как я встречал такие мнения, тот факт, что кто-то думает, что есть переводчик для языка C#, связан с такими проектами, как
или, например, знаменитый
где вы можете написать только строки кода и выполнить их, что наводит на мысль, что это язык, подобный Python, что не соответствует действительности. Он компилирует эти строки и выполняет их, как обычный компилируемый язык программирования (с точки зрения рабочего процесса).
Есть реализация C#, которая является компилируемым языком.
Это остров Remobjects c#, который компилируется непосредственно в двоичный машинный код и запускается без виртуальной машины и без среды выполнения, но использует непосредственно API платформы (win32 для Microsoft, Cocoa для Apple и posix для Linux).
Кроме того, remobjects c# взаимодействует напрямую с скомпилированными библиотеками C/C++, потому что соглашение о вызовах транслируется в соглашение о вызовах c.
Поскольку компьютер может выполнять только двоичный код, любой язык приведет к созданию двоичного кода в тот или иной момент. Вопрос в том, позволяет ли язык создавать программу в двоичном коде? Если да, то это скомпилированный язык: по определению "скомпилированный" в "скомпилированном языке" относится к компиляции в двоичный код, а не к преобразованию в некоторый промежуточный код. Если язык приводит к созданию такого промежуточного кода для программы, ему потребуется дополнительное программное обеспечение для выполнения двоичной компиляции из этого кода: тогда это интерпретируемый язык. Является ли программа, "скомпилированная" с помощью C#, непосредственно исполняемой на машине без какого-либо другого программного обеспечения, установленного на этой машине? если нет, то это интерпретируемый язык. Для интерпретируемого языка это интерпретатор, который будет генерировать базовый двоичный код, в большинстве случаев динамически, поскольку этот механизм является основой гибкости таких языков. денежный перевод иногда это не выглядит очевидным, потому что переводчик включен в ОС
Здесь идут большие дебаты. Я прочитал все ответы и хочу высказать некоторые выводы, основанные на моем исследовании и концепции.
Есть понятие о.
Programming language implementation
: В компьютерном программировании реализация языка программирования представляет собой систему для выполнения компьютерных программ. Существует два основных подхода к реализации языка программирования:
Сборник :
Программа читается компилятором, который переводит ее на какой-то другой язык, например
bytecode or machine code
. Переведенный код может либо выполняться аппаратно напрямую, либо служить входными данными для другого интерпретатора или другого компилятора.Интерпретация:
Интерпретатор — это компьютерная программа, которая непосредственно выполняет инструкции, написанные на языке программирования или языке сценариев, без необходимости их предварительной компиляции в программу на машинном языке.
-
Parse
исходный код и выполнять его поведение напрямую. - Переведите исходный код в какой-нибудь эффективный
intermediate representation or object code
и немедленно выполнить это. - Явно
execute stored precompiled bytecode made by a compiler
и сопоставляется с виртуальной машиной интерпретатора.
-
Выводы:
- Таким образом, любой язык, который преобразует код в промежуточный байтовый код или машинный код, является компилируемым языком.
- Существует несколько типов интерпретаторов, таких как интерпретаторы байтового кода, интерпретаторы точного времени и т. д.
Известные компилируемые языки:
- JAVA C# C C++ GO Котлин Rust
Известные интерпретируемые языки:
- JavaScript PHP Python
Языки с прямой компиляцией и языки, которые сначала компилируются в байт-код:
- Интерпретаторы байт-кода (виртуальные машины), как правило, медленнее, чем прямое выполнение машинного кода. Любой интерпретатор имеет некоторые накладные расходы при преобразовании байт-кода в реальные машинные инструкции.
- Интерпретаторы выполняют построчное выполнение.
- Таким образом, напрямую скомпилированные языки, такие как C++/C, быстрее, чем Java/C#.