Компиляция кода .NET или усложнение? - PullRequest
7 голосов
/ 05 февраля 2010

Q1) Почему C # изначально компилируется в IL, а затем во время выполнения JIT соблюдается и запускается поверх виртуальной машины (?) Или это JIT соответствует родному машинному коду?

Q2) Если второе верно (JIT соответствует собственному машинному коду), то где находится песочница .NET, в которой работает код?

Q3) Кроме того, почему код компилируется в IL в первую очередь. Почему бы просто не скомпилировать в машинный код все время? Существует инструмент от MS, который называется ngen, но почему это необязательно?

Ответы [ 6 ]

12 голосов
/ 05 февраля 2010

IL - это JIT'd (JIT = Just In Time), скомпилированный с собственным машинным кодом при запуске процесса.

Использование уровня виртуальной машины позволяет .NET вести себя согласованно на разных платформах (например, int всегда 32-битный независимо от того, работаете ли вы на 32- или 64-битной машине, это не дело с C ++).

JIT-компиляция позволяет оптимизациям динамически подстраиваться под код во время его выполнения (например, применять более агрессивные оптимизации к частям вызываемого кода или использовать аппаратные инструкции, доступные на конкретной машине, такой как SSE2), которые вы можете делать со статическим компилятором.

3 голосов
/ 05 февраля 2010

A1) JIT компилируется в машинный код

А2) В .net нет такого термина как песочница. Вместо этого есть AppDomains. И они работают как часть CLR (то есть как часть исполняемого процесса)

A3) Недостатки NGen от Джеффри Рихтера:

  • Файлы NGen'd могут быть не синхронизированы. Когда CLR загружает файл NGen'd, он сравнивает количество характеристик о ранее скомпилированном коде и текущем исполнении среда. Если какие-либо характеристики не совпадают, файл NGen'd не может быть используется, и вместо него используется обычный процесс JIT-компилятора.

  • Низкая производительность по времени загрузки (перебазирование / связывание). Файлы сборки - это стандартные файлы Windows PE, и каждый из них содержит предпочтительный базовый адрес. Много окон разработчики знакомы с проблемами, касающимися базовых адресов и перебазирования. При JIT-компиляции кода эти проблемы не имеют значения, поскольку правильные адреса памяти рассчитываются во время выполнения.

  • Низкая производительность во время выполнения. При компиляции кода NGen не может сделать столько предположения о среде выполнения, как это может сделать JIT-компилятор. Это вызывает NGen.exe для создания худшего кода. Например, NGen не оптимизирует использование определенные инструкции процессора; он добавляет косвенные ссылки для доступа к статическому полю, потому что фактический адрес статических полей неизвестен до времени выполнения. NGen вставляет код для вызова класса конструкторы везде, потому что он не знает порядок, в котором будет выполняться код и если конструктор класса уже был вызван.

1 голос
/ 05 февраля 2010

Вы можете использовать NGEN для создания собственных версий ваших сборок .NET. Это означает, что JIT не должен делать это во время выполнения.

.NET сначала компилируется в IL, а затем в нативный, поскольку JIT был разработан для оптимизации кода IL для текущего процессора, под которым выполняется код.

.NET-код компилируется в IL для совместимости. Поскольку вы можете создавать код с использованием C #, VB.NET и т. Д., JIT необходим общий набор команд (IL) для компиляции в собственный код. Если JIT должен знать языки, то JIT нужно будет обновлять при выпуске нового языка .NET.

Я не уверен насчет вопроса о песочнице, я думаю, что приложение .NET работает с 3 доменами приложений. Один домен содержит среды выполнения .NET (mscorlib, system.dll и т. Д.), Другой домен содержит ваш код .NET, и я не могу вспомнить, для чего предназначен другой домен. Проверить http://my.safaribooksonline.com/9780321584090

0 голосов
/ 05 февраля 2010

Скомпилированный .Net код становится IL, который является промежуточным языком точно так же, как и в объектном коде Javas. Да, можно генерировать машинный код с помощью инструмента NGen . NGen связывает получившееся собственное изображение с машиной, поэтому копирование двоичного файла ngen в другую систему не даст ожидаемых результатов. Компиляция в промежуточный код позволяет принимать решения, которые могут быть приняты во время выполнения, которые иначе (легко) не могут быть приняты с помощью языка со статической типизацией, такого как C ++, это также позволяет функционировать кодам на различных аппаратных архетектурах, потому что код становится описательным в ощущение, что оно также описывает намерение того, что должно происходить в битовом (например, 32 или 64) -агностическом смысле, в отличие от машинно-специфичного кода, который работает только в 32-битных или 64-битных системах, но не в обоих.

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

0 голосов
/ 05 февраля 2010

A1) Таким образом, он не зависит от платформы (Windows, Linux, Mac) и может также использовать определенные оптимизации для вашего текущего оборудования. Когда JIT скомпилируется, он превращается в машинный код.

A2) Вся инфраструктура (.NET Framework) - это песочница, поэтому все вызовы, которые вы можете сделать через свое приложение, будут проходить через песочницу .NET Framework.

A3) Как и в ответе 1, он позволяет бинарному файлу .NET работать на разных платформах и выполнять определенные оптимизации на клиентском компьютере на лету.

0 голосов
/ 05 февраля 2010

1. C # скомпилирован в CIL (или IL), потому что он разделяет платформу с остальными языками .NET (поэтому вы можете написать DLL на C # и использовать ее в VB .NET или F # без хлопот). CLR затем JIT скомпилирует код в собственный машинный код.

.NET также может работать на нескольких платформах (Mono на * NIX и OS X). Если C # скомпилирован в нативный код, это будет не так просто.

2. Песочницы нет.

3. Охвачено в ответе на # 1

...