Почему CIL и CLR требуются в .NET?

11

Я видел это хорошее изображение здесь . Я узнал, что все компиляторы, которые поддерживают язык .net, конвертируют исходный код в CILформат. Теперь Microsoft никогда не вводит .NETдля всех операционных систем, написав CLR для всех операционных систем. Тогда зачем сохранять такой промежуточный формат кода и CLR для выполнения этого CIL. Разве это не головная боль, чтобы иметь дело с. Почему Microsoft выбрала именно так?

РЕДАКТИРОВАТЬ Эта своего рода архитектура имеет свою цену. Это снизит производительность, не так ли? Java делает это для поддержания независимости платформы, по какой причине .NET это делает? Почему бы не сохранить простой простой C-подобный компилятор. Любой способ также потребует, чтобы компилятор преобразовал код в CIL, если мне нужно добавить какой-либо новый язык, единственное отличие, которое он сделал бы, - это целевой язык. Тат это все.

vikkyhacks
источник
3
Потому что проще писать компиляторы в CIL. И проще написать один CIL для нативного компилятора, чем компилятор для каждого языка на нативном.
Одед
9
@ratchetfreak: это может быть причиной для MS не переносить CLR на другие платформы, но это не причина для того, чтобы в первую очередь иметь CLR (что на самом деле делает порт проще , поэтому ваш аргумент звучит так же, как MS bashing, извините)
Док Браун
12
Также понижающий голос за 'M $', что это, 1998?
Алан Б
3
Эрик Липперт обсуждает это (начиная с 3-го абзаца; первые 2 абзаца посвящены Рослин). Короткий ответ: комментарий Одеда и ответ Теластина верны; вам нужно всего лишь кодировать <Количество операционных систем> + <Количество языков> компиляторов вместо <Количество операционных систем> * <Количество языков> компиляторов.
Брайан
3
@busy_wait: ссылка на странице упоминает несколько недостатков. Например, «информация о конфигурации в двух приложениях может привести к различным решениям привязки для одной и той же зависимой сборки». Генерация на лету позволяет избежать этих проблем. Это подразумевает, что компиляция действительно должна быть выполнена после распространения приложения (и на самом деле NGEN должен запускаться на каждой целевой машине; он не может быть запущен распространителем).
Брайан

Ответы:

29

Потому что им нужно написать только один компилятор для C # в CIL - это сложная часть. Создание интерпретатора (или чаще всего компилятора Just-In-Time) для CIL для каждой платформы сравнительно легко по сравнению с написанием компилятора из C # для (для каждой платформы) исполняемого кода.

Кроме того, среда выполнения может обрабатывать все, что компилируется в CIL. Если вам нужен новый язык (например, F #), вам нужно написать для него только один компилятор, и вы автоматически получите всю поддержку платформы для вещей, которые поддерживает .NET.

О, и я могу взять dll .NET и запустить его на Windows или Linux через Mono без перекомпиляции (при условии, что все мои зависимости удовлетворены).

Что касается производительности, это спорно. По сути, существуют «прекомпиляторы», которые принимают CIL и создают собственные двоичные файлы. Другие утверждают, что компиляторы точно в срок могут делать оптимизации, которые статические компиляторы просто не могут. По моему опыту, это во многом зависит от того, что делает ваше приложение и на какой платформе вы его запускаете (в основном, насколько хорош JITer на этой платформе). Мне крайне редко приходится сталкиваться со сценарием, в котором .NET недостаточно хорош .

Telastyn
источник
"Переводчик" `? Я думал, что всегда MS обеспечивает только JITter?
Док Браун
1
@DocBrown - да, да - неправильно с моей стороны. Закрепление.
Теластин
+1, не могли бы вы добавить немного пояснения к моему редактированию, чтобы я мог принять этот ответ
vikkyhacks
Высокопроизводительные среды выполнения часто объединяют интерпретатор и JIT-компилятор (выполнение в смешанном режиме). Я не уверен в .NET, но многие виртуальные машины Java используют этот подход.
Cyanfish
2
@busy_wait: все виды вещей. Встраивание методов, копирование распространения, удаление ненужного кода, преобразование умножений / делений в сдвиги, другие арифметические операции с использованием readonlyполей. Традиционные компиляторы могут выполнять некоторые из этих оптимизаций, но только тогда, когда они могут быть обнаружены статическим анализом. Напротив, джиттер может обнаружить во время выполнения, что (например) часть кода не выполняет никакой полезной работы, потому что на изменяемые объекты или переменные больше не ссылаются. Я не эксперт по дрожаниям, но в основном это вопрос силы динамического и статического анализа.
Aaronaught
14

.NET имеет промежуточный язык (CIL / MSIL) и специфичные для платформы реализации независимой от платформы среды выполнения (CLR) по той же причине, что и в Java. Microsoft планировала, что C # будет напрямую конкурировать с Java, и это действительно так, в операционных системах, на которые ориентирована Microsoft (своей собственной).

Преимущества, даже несмотря на то, что .NET поддерживается только на платформах Windows (или в других операционных системах, имеющих аналог .NET, таких как Mono / Linux), аналогичны Java:

  • Runtime для управляемой памяти - в отличие от неуправляемых C / C ++, разработчикам на C # / VB.NET не нужно беспокоиться о строгом контроле времени жизни объектов. Как и в Java, в CLR есть сборщик мусора, который автоматически освобождает объекты в куче, которые выходят из области видимости. Хотя это может показаться незначительным для тех, кто привык к неуправляемым средам выполнения, он имеет крайне дополнительное преимущество, заключающееся в том, что он препятствует «черной магии» арифметики указателей, столь распространенной в C / C ++.
  • Независимость от платформы - Windows Vista и Windows 7 работают не так, как Windows XP. Windows 8 работает по-прежнему по-другому. Версии Windows Mobile, включая Windows 8 Mobile, снова работают по-другому. Разное оборудование, разная архитектура, разные возможности. Хотя целевая среда по-прежнему имеет значение для разработчика .NET, объем специализированных знаний намного меньше по сравнению с тем, что необходимо знать для создания совместимой программы на C / C ++ для всех этих ОС. AC # dev получает намного больше бесплатно.
  • Поддержка веб-приложений - я еще не видел клиентского веб-приложения, написанного на сервере и написанного с нуля на C ++. Веб- сервер , Apache, ISS, конечно, все они обычно работают против неуправляемой среды выполнения по соображениям скорости / эффективности. Однако C ++ не является языком, используемым для создания веб-приложений. C # есть (как и Java). Он был разработан с нуля для поддержки следующего поколения парадигмы Microsoft ASP. Это код, предназначенный для запуска в песочнице; какая песочница (плагин ASP.NET для ISS или "настольный" CLR) относительно неважна.
  • Независимость от языка / среды выполнения - компилятор C ++ берет исходный код C ++ и создает ассемблерный код для архитектуры с одним процессором, используя один машинный язык. Для поддержки другой архитектуры и / или машинного языка должен быть написан совершенно новый компилятор (и должен быть скомпилирован совершенно новый набор библиотек времени выполнения). Компилятор AC # берет исходный код C # и создает CIL, который аппаратно-зависимый JITer преобразует в машинный код. Один и тот же JITer может переводить любую CIL-программу независимо от того, на каком языке она написана (и их несколько; C #, VB.NET, F # и множество портов «Iron», таких как IronHaskell, IronRuby, IronLisp и т. Д.). Один и тот же компилятор может превратить один язык в CIL, который может запустить любой JITer, независимо от аппаратного обеспечения.
  • Сосредоточьтесь на «правильном» коде - для разработчиков C ++ существует множество «правильных» способов сделать что-то, в зависимости от того, что является наиболее важным; эффективность памяти, эффективность процессора, аппаратная независимость, независимость от ОС и т. д. Код может сильно отличаться, когда каждый из них является приоритетным. C # был разработан группой, которая приняла концептуальные уроки Фаулера и его коллег (которые работали, чтобы реформировать дизайн кода в сообществе C ++, обучая объектно-ориентированные принципы сообществу, которое в значительной степени перешло в него из C), как а также практические уроки, извлеченные из языков, которые были до этого (включая Java, и его почти фанатичное подчинение всемогущему объекту, когда старый добрый указатель на функцию в стиле C ++ будет выполнять работу намного более чисто и не будет менее объектно-ориентированным). ориентированный).

По причинам антимонопольного законодательства MS старается не допускать слишком сильного вмешательства в другие основные платформы, такие как Android, Mac OSX / iOS и Linux; однако, у него действительно есть команды, разрабатывающие для всех трех этих платформ. Существует версия Office для OSX, разработанная MS, есть множество приложений, в том числе приложения взаимодействия Office для iOS и Android, Skype (теперь продукт Microsoft) работает на Linux, и Microsoft даже видела вклад в ядро ​​Linux (в основном в виртуализация мышления).

Keiths
источник
1
«Я еще не видел клиентского веб-приложения, написанного на сервере и написанного с нуля на C ++». - где вы помещаете CGIs старых дней? Мои самые первые веб-приложения (какими бы тривиальными они ни были) были на 100% C. Тогда (в середине 90-х) было проще написать .c и .h для выполнения стандартной работы в cgi (языки сценариев были просто выходит на сцену тоже).
хм ... CGI, CGI ... Я думаю, что слышал об этом, но я с KeithS, я еще не видел его :)
ДХМ
@DXM старая модель динамического контента была для веб-сервера вилкой процесса и помещала вещи в стандартные места (параметры запроса и тому подобное шли в определенных переменных среды) - Common Gateway Interface. Выходные данные этого процесса были затем отправлены обратно как содержимое. В старые времена было легче найти программиста, который знал C или C ++, а не perl или python (и sh был очень неуклюжим для такой работы).
1
Не стоит недооценивать важность сходства с Java. Sun только что подала в суд на MS за их порт JVM и выиграла несколько юридических пунктов (глупо, ИМХО). CIL и CLR вдохновлены этим, и вы заметите, что J # настолько близок, насколько это возможно, к Java, не вызывая дальнейших юридических действий. Огромная разница в том, что CLR не зависит от языка. Вы действительно можете написать программу на смеси C #, F # и J #, если это то, что нужно. Просто попробуйте смешать Java с библиотеками на других языках и получить стабильную программу.
RBerteig
1
Но взаимодействие между MSIL и нативным кодом достаточно хорошо определено и просто работает. И, видимо, ожидалось, что он будет работать как по дизайну, так и по мнению сообщества пользователей.
RBerteig
12

Операционная система Windows доступна для разных типов процессоров, сегодня это в основном x64, x86, Intel, ARM.

CIL / CLR не зависит от этой аппаратной платформы - эти различия «абстрагируются» средой исполнения IL. Например, сборка .NET, скомпилированная для «любого процессора», обычно может выполняться на Win64 как 64-битный процесс, а Win32 - как 32-битный процесс без необходимости предоставления различных исполняемых файлов.

Более того, CIL позволяет хранить метаданные в сборках, что нелегко сделать с помощью собственных DLL (возможно, конечно, MS делала это раньше с COM-компонентами, но с этой технологией никогда не было так легко обращаться, как с компонентами .NET). Это делает создание программных компонентов чертовски простым и является основой для размышлений / самоанализа во всех языках .NET.

Док Браун
источник
Просто чтобы добавить к этому немного, они не только допускают разные типы процессоров, но даже разные версии (Core i3 / i5 / i7), а производители (Intel и AMD) в рамках одного и того же типа процессора (например, все x64) могут иметь разные наборы инструкций по сборке, которые JIT-компилятор сможет использовать в своих интересах
DXM
2
@DXM: а вы знаете, что JIT на самом деле? Или это скорее гипотетическая вещь?
Док Браун
По крайней мере в блоге MSDN утверждается, что JIT-компилятор делает это (или делал это 8 лет назад).
@DocBrown: Очевидно, у меня нет справочного материала, но я подумал, что вспомнил, что читал об этом давным-давно. Спасибо Делнан, что нашел ссылку. Это имеет смысл, поскольку мы знаем, что производители микросхем предпочитают добавлять свои собственные инструкции поверх стандартной x86-x64, поэтому, если машина может воспользоваться этим преимуществом, почему бы и нет?
ДХМ