Perché CIL e CLR sono richiesti in .NET?


11

Ho visto questa bella immagine qui . Ho imparato che tutti i compilatori che supportano il linguaggio .net convertono il codice sorgente in CILformato. Ora Microsoft non inserisce mai .NETper tutto il sistema operativo scrivendo un CLR per tutti i sistemi operativi. Quindi perché mantenere un tale formato di codice intermedio e un CLR per eseguire quel CIL. Non è un mal di testa da affrontare. Perché Microsoft ha scelto di essere così?

EDIT Questa architettura ha un suo prezzo. Ridurrà le prestazioni, no? Java fa questo per mantenere l'indipendenza della piattaforma, per quale motivo .NET lo fa? Perché non mantenere un semplice compilatore come C semplice. In ogni caso sarà anche necessario un compilatore per convertire il codice in CIL se devo aggiungere una nuova lingua, l'unica differenza che farebbe sarebbe la lingua di destinazione. Tat è tutto.


3
Perché è più facile scrivere compilatori su CIL. Ed è più semplice scrivere un CIL nel compilatore nativo rispetto a un compilatore in ogni lingua in nativo.
Oded,

9
@ratchetfreak: questo potrebbe essere un motivo per cui MS non ha portato il CLR su altre piattaforme, ma non è un motivo per avere un CLR in primo luogo (il che rende una porta più semplice , quindi il tuo argomento suona proprio come il bashing di MS, scusate)
Doc Brown,

12
Votazione anche per "M $", che cos'è questo, 1998?
Alan B,

3
Ne discute Eric Lippert (a partire dal terzo paragrafo; i primi 2 paragrafi riguardano Roslyn). La risposta breve è che il commento di Oded e la risposta di Telastyn sono giusti; devi solo compilare i compilatori <Numero di sistemi operativi> + <Numero di lingue> anziché <Numero di sistemi operativi> * <Numero di lingue> compilatori.
Brian,

3
@busy_wait: la pagina di riferimento menziona alcuni aspetti negativi. Ad esempio, "le informazioni di configurazione in due applicazioni potrebbero comportare decisioni di associazione diverse per lo stesso assembly dipendente". Generare al volo evita questi problemi. Ciò implica che la compilazione deve davvero essere eseguita dopo che l'app è stata distribuita (e in effetti, NGEN deve essere eseguito su ogni macchina di destinazione; non può essere eseguito dal distributore).
Brian,

Risposte:


29

Perché devono solo scrivere un compilatore per C # in CIL, che è la parte difficile. Creare un interprete (o più spesso, compilatore Just-In-Time) per il CIL per piattaforma è relativamente semplice rispetto alla scrittura di un compilatore dal codice eseguibile C # a (per piattaforma).

Oltre a ciò, il runtime può gestire tutto ciò che viene compilato in CIL. Se vuoi un nuovo linguaggio (come F #) devi solo scrivere un compilatore per esso e otterrai automaticamente tutto il supporto della piattaforma per cose che .NET supporta.

Oh, e posso prendere una DLL .NET ed eseguirla su Windows o Linux via Mono senza ricompilazione (supponendo che tutte le mie dipendenze siano soddisfatte).

Per quanto riguarda le prestazioni, è discutibile. Esistono essenzialmente "pre-compilatori" che prendono il CIL e creano binari nativi. Altri sostengono che i compilatori just-in-time possono fare ottimizzazioni che i compilatori statici semplicemente non possono. Nella mia esperienza, dipende molto da cosa sta facendo la tua applicazione e da quale piattaforma la stai eseguendo (principalmente quanto è buono JITer su quella piattaforma). È estremamente raro per me imbattermi in uno scenario in cui .NET non era abbastanza buono .


"interprete" `? Ho pensato che MS fornisce sempre solo un JITter?
Doc Brown,

1
@DocBrown - eh, sì - improprio da parte mia. Fissaggio.
Telastyn,

+1, puoi aggiungere un po 'di spiegazione per la mia modifica in modo che io possa accettare questa risposta
vikkyhacks

I runtime ad alte prestazioni spesso combinano un interprete e un compilatore JIT (esecuzione in modalità mista). Non sono sicuro di .NET, ma molte VM Java usano questo approccio.
Cyanfish,

2
@busy_wait: cose di ogni genere. Metodo di allineamento, copia della propagazione, rimozione di codice non necessario, conversione di moltiplicazioni / divisioni in turni, altre operazioni aritmetiche tramite readonlycampi. I compilatori tradizionali possono eseguire alcune di queste ottimizzazioni, ma solo quando possono essere rilevati mediante analisi statiche. Al contrario, un jitter può scoprire in fase di esecuzione che (ad esempio) una sezione di codice non sta facendo alcun lavoro utile perché gli oggetti o le variabili che modifica non fanno riferimento in nessun altro luogo. Non sono un esperto di nervosismo ma è fondamentalmente una questione di potere dell'analisi dinamica vs. statica.
Aaronaught,

14

.NET ha un linguaggio intermedio (CIL / MSIL) e implementazioni specifiche della piattaforma di un runtime indipendente dalla piattaforma (CLR) per lo stesso motivo di Java. Microsoft intendeva che C # competesse direttamente con Java e lo fa sui sistemi operativi che Microsoft ha scelto (di per sé).

I vantaggi, sebbene .NET sia supportato solo su piattaforme Windows (o altri sistemi operativi che hanno un funzionamento simile a .NET come Mono / Linux), sono simili a Java:

  • Managed Memory Runtime - A differenza di C / C ++ non gestito, gli sviluppatori C # / VB.NET non devono preoccuparsi di controllare rigorosamente la durata degli oggetti. Come Java, CLR ha un garbage collector che libera automaticamente gli oggetti nell'heap che lasciano l'ambito. Mentre questo può sembrare minore per qualcuno abituato a runtime non gestiti, ha l'estremo vantaggio secondario di scoraggiare la "magia nera" dell'aritmetica del puntatore che è così comune in C / C ++.
  • Indipendenza dalla piattaforma: Windows Vista e Windows 7 funzionano in modo diverso da Windows XP. Windows 8 funziona ancora in modo diverso. Le versioni di Windows Mobile incluso Windows 8 Mobile funzionano di nuovo in modo diverso. Hardware diverso, architettura diversa, capacità diverse. Mentre l'ambiente di destinazione è ancora importante per uno sviluppatore .NET, la quantità di conoscenza specializzata è molto ridotta rispetto a ciò che deve essere noto per costruire un programma C / C ++ compatibile per tutti questi sistemi operativi. AC # dev ottiene molto di più gratuitamente.
  • Supporto per applicazioni Web - Non ho ancora visto un'applicazione Web rivolta al client, basata su server, scritta da zero in C ++. Il web server , sicuramente, Apache, ISS, in genere funzionano tutti contro un runtime non gestito per motivi di velocità / efficienza. Tuttavia, C ++ non è un linguaggio utilizzato per la creazione di applicazioni Web. C # è (come è Java). È stato progettato da zero per supportare la prossima generazione del paradigma ASP di Microsoft. Questo è il codice progettato per essere eseguito in un sandbox; quale sandbox (il plug-in ASP.NET per ISS o CLR "desktop") è relativamente poco importante.
  • Indipendenza dal linguaggio / runtime - Un compilatore C ++ prende il codice sorgente C ++ e produce il codice assembly per un'architettura di processore usando un linguaggio macchina. Per supportare una diversa architettura e / o linguaggio macchina, è necessario scrivere un compilatore completamente nuovo (e compilare un set completamente nuovo di librerie di runtime). Il compilatore AC # prende il codice sorgente C # e produce CIL, che il JITer specifico dell'hardware traduce in codice macchina. Lo stesso JITer può tradurre qualsiasi programma CIL indipendentemente dalla lingua di origine (e ce ne sono diverse; C #, VB.NET, F # e una serie di porte per la lingua "Iron" come IronHaskell, IronRuby, IronLisp, ecc.). Lo stesso compilatore può trasformare una lingua in CIL che può essere eseguita da qualsiasi JITer, indipendentemente dall'hardware.
  • Concentrati sul codice "corretto" - Per gli sviluppatori C ++, ci sono molti modi "giusti" per fare qualcosa, a seconda di ciò che è più importante; efficienza della memoria, efficienza della CPU, indipendenza dell'hardware, indipendenza del sistema operativo, ecc. Il codice può apparire drasticamente diverso quando ognuno di questi è la priorità. C # è stato progettato da un gruppo che ha preso a cuore le lezioni concettuali di Fowler e dei suoi colleghi (che stavano lavorando per riformare la progettazione del codice all'interno della comunità C ++ insegnando principi orientati agli oggetti a una comunità che si è trasferita in gran parte da C), come così come le lezioni pratiche apprese dai linguaggi precedenti (incluso Java, e la sua obbedienza quasi fanatica all'Onnipotente Oggetto, quando un buon vecchio puntatore a funzioni in stile C ++ farebbe il lavoro in modo molto più pulito e non sarebbe meno oggetto- orientate).

Per ragioni antitrust, la MS sta attenta a non essere vista "interferire" troppo pesantemente in altre piattaforme importanti come Android, Mac OSX / iOS e Linux; tuttavia, ha davvero team di sviluppo per tutte e tre queste piattaforme. Esiste una versione di Office per OSX sviluppata da MS, ci sono numerose applicazioni tra cui app di interoperabilità di Office per iOS e Android, Skype (ora un prodotto Microsoft) gira su Linux e Microsoft ha persino visto contribuire al kernel Linux (principalmente in un mentalità di virtualizzazione).


1
"Non ho ancora visto un'applicazione web rivolta al client, basata su server, scritta da zero in C ++." - dove metti CGI di vecchi tempi? Le mie primissime applicazioni web (per quanto banali) erano al 100% C. All'epoca (metà degli anni '90) era più facile scrivere un .c e .h per fare il lavoro standard in cgi (i linguaggi 'scripting' erano solo emergendo anche sulla scena).

hm ... CGI, CGI ... Penso di averne sentito parlare, ma sto con KeithS, devo ancora vederne uno :)
DXM

@DXM il vecchio modello di contenuto dinamico era per il web server fork di un processo e metteva le cose in posizioni standard (parametri di query e simili andavano in specifiche variabili di ambiente) - Common Gateway Interface. L'output di quel processo è stato quindi rispedito come contenuto. Ai vecchi tempi, era più facile trovare un programmatore che conosceva C o C ++ piuttosto che perl o python (e sh era molto goffo per tale lavoro).

1
Non sottovalutare l'importanza della somiglianza con Java. Sun aveva appena fatto causa alla MS per il suo porto della JVM e aveva vinto alcuni punti legali (stupidamente, IMHO). CIL e CLR ne sono ispirati e noterai che J # è il più vicino possibile a Java senza innescare ulteriori azioni legali. Un'enorme differenza è che il CLR è indipendente dalla lingua. Puoi davvero scrivere un programma in un mix di C #, F # e J # se questo è ciò che è necessario. Basta provare a mescolare Java con le librerie in altre lingue e ottenere un programma stabile.
RBerteig,

1
Ma l'interoperabilità tra MSIL e il codice nativo è ragionevolmente ben definita e funziona. E apparentemente ci si aspettava che funzionasse solo in base alla progettazione e agli atteggiamenti della comunità di utenti.
RBerteig,

12

Il sistema operativo Windows è disponibile per diversi tipi di CPU, oggi principalmente x64, x86, Intel, ARM.

CIL / CLR è indipendente da quella piattaforma hardware - queste differenze sono "astratte" dall'ambiente di esecuzione di IL. Ad esempio, un assembly .NET compilato per "qualsiasi CPU" può in genere essere eseguito su Win64 come processo a 64 bit e Win32 come processo a 32 bit, senza la necessità di fornire diversi eseguibili.

Inoltre, il CIL consente di archiviare i metadati in assiemi che non è facilmente possibile con le DLL native (è possibile, naturalmente, MS lo ha fatto prima con i componenti COM, ma quella tecnologia non è mai stata così facile da gestire come i componenti .NET). Ciò rende la creazione di componenti software molto più semplice ed è il fondamento della riflessione / introspezione in tutti i linguaggi .NET.


Solo per aggiungere un po 'a questo, non solo consentono diversi tipi di CPU ma anche versioni diverse (Core i3 / i5 / i7) e fornitori (Intel vs AMD) all'interno dello stesso tipo di CPU (tutti x64 per esempio) potrebbero avere diversi serie di istruzioni di assemblaggio che il compilatore JIT sarebbe in grado di sfruttare
DXM

2
@DXM: e sai che la JIT lo fa davvero? O è più una cosa ipotetica?
Doc Brown,

Almeno un blog MSDN afferma che il compilatore JIT lo fa (o l'ha fatto 8 anni fa).

@DocBrown: Ovviamente non ho materiale di riferimento a portata di mano, ma pensavo di essermi ricordato di aver letto qualcosa su questo tanto tempo fa. Grazie delnan, per aver trovato il link. Avrebbe senso dal momento che sappiamo che ai produttori di chip piace aggiungere le proprie istruzioni in aggiunta allo standard x86-x64, quindi se la macchina può trarne vantaggio perché non dovrebbe?
DXM,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.