C # частично интерпретируется или действительно компилируется? - PullRequest
62 голосов
/ 12 января 2012

Существует много противоречивой информации об этом. В то время как некоторые говорят, что C # компилируется (так как он компилируется в IL, а затем в нативный код при запуске), другие говорят, что он интерпретируется так, как ему нужно .NET. EN Wiki говорит:

Многие интерпретируемые языки сначала компилируются в какую-то виртуальную форму машинный код, который затем интерпретируется или компилируется во время выполнения к нативному коду.

Так что я в замешательстве. Может ли кто-нибудь объяснить это ясно?

Ответы [ 13 ]

61 голосов
/ 12 января 2012

C # компилируется в IL компилятором c #.

Этот IL затем компилируется точно в срок (JIT) по мере необходимости на родном языке ассемблера хост-машины. Впрочем, можно было бы написать среду выполнения .NET, которая интерпретировала бы IL. Даже если бы это было сделано, я бы до сих пор утверждал, что c # - это скомпилированный язык.

34 голосов
/ 12 января 2012

Чисто скомпилированный язык имеет некоторые преимущества. Скорость, как правило, и часто рабочий размер набора. Чисто интерпретированный язык имеет некоторые преимущества. Гибкость, не требующая явной стадии компиляции, которая позволяет нам редактировать на месте, и часто более простая переносимость.

В этом случае смешанный язык вписывается в середину.

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

C # также может быть скомпилирован при первом запуске, как это происходит в ASP.NET, что делает его близким к интерпретируемому в этом случае (хотя он все еще компилируется в IL и затем в этом случае подключается) Конечно, в этом случае он обладает практически всеми преимуществами интерпретации (сравните с VBScript или JScript, используемым в классическом ASP), а также многими преимуществами компилируемого.

Строго говоря, ни один язык не может быть скомпонован, интерпретирован или скомпилирован как язык. Мы можем использовать NGen C # для собственного кода (хотя, если он делает что-то вроде динамической загрузки сборки, он все равно будет использовать IL и джиттинг). Мы могли бы написать intepretter для C или C ++ (несколько человек сделали это). Однако в наиболее распространенном случае использования C # компилируется в IL, который затем соединяется, что не совсем классическое определение интерпретируемого и компилируемого.

14 голосов
/ 17 января 2016

Слишком много семантики и утверждений, основанных на мнении.

Прежде всего: C # не является интерпретируемым языком; CLR и JVM считаются средой выполнения или промежуточным программным обеспечением, но одно и то же имя относится к таким вещам, как Perl. Это создает путаницу среди людей, связанных с именами.

Термин «Интерпретатор», ссылающийся на среду выполнения, обычно означает, что существующий код интерпретирует некоторый не родной код. Существует две большие парадигмы: парсинг читает исходный код и выполняет логические действия; Выполнение байт-кода сначала компилирует код в ненативное двоичное представление, для интерпретации которого требуется гораздо меньше циклов ЦП.

Java изначально скомпилирована в байт-код, затем прошла через интерпретатор; теперь JVM читает байт-код и как раз вовремя компилирует его в нативный код. CIL делает то же самое: CLR использует своевременную компиляцию для собственного кода.

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

В качестве примера: во многих интерпретируемых языках используется своевременная компиляция байт-кода. C # компилируется в CIL, который JIT компилирует в native; напротив, Perl немедленно компилирует скрипт в байт-код, а затем запускает этот байт-код через интерпретатор. Вы можете запустить сборку C # только в формате байт-кода CIL; Вы можете запускать только Perl-скрипт в формате исходного кода.

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

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

11 голосов
/ 12 января 2012

Смотрите здесь: http://msdn.microsoft.com/library/z1zx9t92

Исходный код, написанный на C #, компилируется в промежуточный язык (IL), который соответствует спецификации CLI.

(...)

При выполнении программы на C # сборка загружается в CLR, что может выполнять различные действия в зависимости от информации в манифесте.Затем, если требования безопасности соблюдены, CLR выполняет компиляцию точно в срок (JIT) для преобразования кода IL в собственные машинные инструкции.

10 голосов
/ 28 июня 2014

Если вы чувствуете, узнали или ушли из старой школы, что скомпилированный EXE идет от исходного кода к машинному коду, тогда интерпретируется C #.Если вы думаете, что скомпилированный означает преобразование исходного кода в другой код, такой как байт-код, то да, он преобразован.Для меня все, что требует обработки во время выполнения для работы в ОС, для которой оно было построено, интерпретируется.

4 голосов
/ 21 ноября 2012

Для начала давайте разберемся с определениями интерпретации и компиляции.

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

«Интерпретировать» (при обращении к коду) ТАКЖЕ означает перевод кода с одного языка на другой. Но на этот раз он обычно используется для перехода от удобочитаемого исходного кода к промежуточному коду, который берется виртуальной машиной, которая интерпретирует его в машинный код.

Просто чтобы прояснить
Исходный код -> Компилятор -> Машинный код
Исходный код -> Компилятор -> Байт-код -> Интерпретатор -> Машинный код

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

Безусловно, все это маркетинговый трюк. Термин «интерпретированный» был добавлен (или, по крайней мере, увеличен в использовании), чтобы показать, насколько аккуратной была своевременная компиляция . Но они могли просто использовать «скомпилированный». Различие заключается скорее в изучении английского языка и тенденций в бизнесе, чем в техническом аспекте.

2 голосов
/ 24 января 2019

Большинству языков, если не всем, требуется переводчик, который переводит свои сценарии в машинные коды, чтобы процессор мог понять и выполнить его!

Каждый язык обрабатывает перевод по-своему!

Например, «AutoIt» - это то, что мы можем описать как язык с 100% интерпретацией!

почему

Потому что интерпретатор "AutoIt" ​​постоянно нужен, пока выполняется его скрипт! Смотрите пример ниже:

Loop, 1000
Any-Code

Интерпретатор "AutoIt" ​​должен будет переводить "Any-Code" 1000 раз в машинный код, что автоматически делает "AutoIt" ​​медленным языком!

С другой стороны, C # по-разному обрабатывает процесс перевода, интерпретатор C # требуется только один раз, до выполнения скрипта, после чего он больше не требуется во время выполнения скрипта!

Переводчик C # должен будет переводить «Any-Code» только один раз в машинный код, что автоматически делает «C #» быстрым языком!

Так в основном,

  • Язык, который требует своего интерпретатора во время выполнения скрипта, является "Интерпретируемым языком"!

  • Язык, который требует своего интерпретатора только один раз (до выполнения скрипта), является "Скомпилированным языком"!

Наконец,

  • «AutoIt» - это «Интерпретированный язык»!

  • "C #" - это "скомпилированный язык"!

2 голосов
/ 20 января 2013

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

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

«Скомпилированный язык» является неправильным в некотором смысле, потому что скомпилированный или интерпретированный является не свойством языка, а средой выполнения.

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

1 голос
/ 13 октября 2017

Я считаю, что это довольно старая тема.

С моей точки зрения, интерпретируемый код будет проходить через интерпретатор, построчно переводить и исполняться одновременно. Как и пример javascript, это интерпретируемый код, когда в строке javascript возникла ошибка, скрипт просто сломается.

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

0 голосов
/ 07 ноября 2017

Если мы согласны с определением интерпретатора « В информатике интерпретатор - это компьютерная программа, которая непосредственно выполняет, то есть выполняет инструкции, написанные на языке программирования или на языке сценариев, не требуя, чтобы они были предварительно скомпилированы в программа на машинном языке. »нет сомнений: C # не является интерпретируемым языком.

Переводчик в Википедии

...