Чому в .NET потрібні CIL та CLR?


11

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

EDIT Ця своєрідна архітектура має свою ціну. Це знизить продуктивність, чи не так? Java робить це для підтримки незалежності платформи, з якої причини .NET це робить? Чому б не зберегти простий звичайний C, як компілятор. Будь-який спосіб також зажадає компілятора для перетворення коду в CIL, якщо мені потрібно буде додати будь-яку нову мову, єдина різниця, яку це зробить, - це цільова мова. Тат все.


3
Тому що простіше написати компілятори до CIL. І простіше написати один CIL до рідного компілятора, ніж компілятор до кожної мови, а до рідної.
Одід

9
@ratchetfreak: що може бути причиною для MS для НЕ портирование CLR на інші платформи, але не привід для мати CLR в першу чергу (що на насправді зробити порт простіше , так що ваш аргумент звук так само , як MS прочухана, вибачте)
Doc Brown

12
Також підкреслив "M $", що це за 1998 рік?
Алан Б

3
Ерік Ліпперт обговорює це (починаючи з 3-го абзацу; перші два абзаци - про Рослін). Коротка відповідь полягає в тому, що коментар Одеда і відповідь Теластина є правильними; вам потрібно лише кодувати <Кількість операційних систем> + <Кількість мов> компілятори замість <Кількість операційних систем> * <Кількість мов> компілятори.
Брайан

3
@busy_wait: на зазначеній сторінці згадується кілька недоліків. Наприклад, "інформація про конфігурацію у двох додатках може призвести до різних обов'язкових рішень для однієї і тієї ж залежної збірки". Генерація на льоту уникає цих проблем. Це означає, що компіляцію дійсно потрібно робити після розповсюдження програми (а насправді NGEN повинен працювати на кожному цільовому апараті; дистриб'ютор не може запускатись).
Брайан

Відповіді:


29

Тому що їм потрібно написати лише один компілятор для C # в CIL - що є важкою частиною. Зробити інтерпретатора (або частіше - компілятора Just-In-Time) для CIL на платформу порівняно просто порівняно з написанням компілятора з виконуваного коду від C # до (на платформу).

Крім цього, час виконання може обробляти все, що компілюється в CIL. Якщо ви хочете нову мову (наприклад, F #), вам потрібно написати лише один компілятор, і ви автоматично магічно отримаєте всю підтримку платформи для речей .NET.

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

Щодо продуктивності, то це дискусійно. По суті, є "попередні компілятори", які беруть CIL і роблять нативні бінарні файли. Інші стверджують, що вчасно встановлені компілятори можуть зробити оптимізацію, що статичні компілятори просто не можуть. На мій досвід, багато що залежить від того, чим займається ваша програма та на якій платформі ви працюєте (переважно, наскільки хороший JITer на цій платформі). Мені надзвичайно рідко трапляється сценарій, коли .NET був недостатньо хорошим .


"перекладач" `? Я думав, що 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:

  • Керована обсяг пам’яті - на відміну від некерованого 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 ++, викладаючи об'єктно-орієнтовані принципи для спільноти, яка значною мірою перейшла до неї із С), як а також практичні уроки, засвоєні мовами, що були раніше (включаючи Java, і її майже фанатичне послух всемогутньому Об'єкту, коли старий добрий вказівник функції стилю C ++ зробив би цю роботу набагато чіткіше і не був би меншим об'єктом, орієнтований).

З антимонопольних причин MS обережно не сприймає «занадто сильного втручання» в інші основні платформи, такі як Android, Mac OSX / iOS та Linux; однак у нього дійсно є команди, що розробляють для всіх трьох цих платформ. Існує розроблена MS версія версії Office для OSX, є численні додатки, включаючи додатки Office interop для iOS та Android, Skype (зараз продукт Microsoft) працює на Linux, і Microsoft навіть бачила внесок у ядро ​​Linux (насамперед у віртуалізація мислення).


1
"Я ще не бачив веб-застосунку, орієнтованого на клієнта, написаного на сервер, написаного з нуля на C ++." - куди ти ставиш КГІ старих днів? Мої найперші веб-додатки (настільки тривіальні, як вони були) були на 100% C. Тоді (у середині 90-х) було легше писати .c та .h для виконання стандартної роботи в cgi (мови "сценаріїв" були просто з'являються на сцені теж).

гм ... CGI, CGI ... Я думаю, що я чув про це, але я з KeithS, я ще насправді бачу його :)
DXM

@DXM стара модель динамічного вмісту для веб-сервера розщедрила процес і розмістила речі у стандартних місцях (парами запитів тощо), що надходили у певні змінні середовища) - загальний інтерфейс шлюзу. Потім результат цього процесу був відправлений назад як вміст. За старих часів було легше знайти програміста, який знав C або C ++, а не perl чи python (і sh був дуже незграбний для такої роботи).

1
Не варто недооцінювати важливість подібності з Java. Sun щойно подав до суду на MS за їхній порт JVM і виграв деякі юридичні бали (тупо, IMHO). 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, тож якщо машина може скористатися, чому б це не зробити?
DXM
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.