Pourquoi CIL et CLR sont-ils requis dans .NET?

11

J'ai vu cette belle image ici . J'ai appris que tous les compilateurs qui prennent en charge le langage .net convertissent le code source au CILformat. Désormais, Microsoft n'intègre jamais .NETtout le système d'exploitation en écrivant un CLR pour tous les systèmes d'exploitation. Alors pourquoi garder un tel format de code intermédiaire et un CLR pour exécuter ce CIL. N'est-ce pas un casse-tête à gérer. Pourquoi Microsoft a-t-il choisi d'être comme ça?

EDIT Cette architecture a un prix. Cela réduira les performances, non? Java le fait pour maintenir l'indépendance de la plate-forme, pour quelle raison .NET le fait-il? Pourquoi ne pas garder un simple compilateur en C simple. De toute façon, il faudra également un compilateur pour convertir le code en CIL si j'ai besoin d'ajouter une nouvelle langue, la seule différence que cela ferait est la langue cible. Tat est tout.

vikkyhacks
la source
3
Parce qu'il est plus facile d'écrire des compilateurs dans CIL. Et il est plus facile d'écrire un CIL dans un compilateur natif qu'un compilateur dans chaque langue en natif.
Oded
9
@ratchetfreak: cela peut être une raison pour que MS ne porte pas le CLR vers d'autres plates-formes, mais ce n'est pas une raison pour avoir un CLR en premier lieu (ce qui rend en fait un port plus facile , donc votre argument sonne comme MS bashing, désolé)
Doc Brown
12
Aussi downvote pour 'M $', qu'est-ce que c'est, 1998?
Alan B
3
Eric Lippert en discute (à partir du 3ème paragraphe; les 2 premiers paragraphes concernent Roslyn). La réponse courte est que le commentaire d'Oded et la réponse de Telastyn sont exacts; il vous suffit de coder <nombre de systèmes d'exploitation> + <nombre de langues> compilateurs au lieu de <nombre de systèmes d'exploitation> * <nombre de langues> compilateurs.
Brian
3
@busy_wait: La page référencée mentionne quelques inconvénients. Par exemple, «les informations de configuration dans deux applications peuvent entraîner des décisions de liaison différentes pour le même assembly dépendant». Générer à la volée évite ces problèmes. Cela implique que la compilation doit vraiment être effectuée après la distribution de l'application (et en fait, NGEN doit être exécuté sur chaque machine cible; il ne peut pas être exécuté par le distributeur).
Brian

Réponses:

29

Parce qu'ils n'ont besoin d'écrire qu'un seul compilateur pour C # vers CIL - ce qui est la partie difficile. Faire un interprète (ou plus souvent, un compilateur Just-In-Time) pour le CIL par plate-forme est relativement facile par rapport à l'écriture d'un compilateur de C # en (par plate-forme) de code exécutable.

Au-delà, le runtime peut gérer tout ce qui se compile en CIL. Si vous voulez un nouveau langage (comme F #), vous n'avez qu'à écrire un compilateur pour celui-ci et vous obtenez automatiquement tout le support de la plate-forme pour les choses que .NET prend en charge.

Oh, et je peux prendre une DLL .NET et l'exécuter sur Windows ou sur Linux via Mono sans recompilation (en supposant que toutes mes dépendances sont satisfaites).

Quant aux performances, c'est discutable. Il existe essentiellement des "pré-compilateurs" qui prennent le CIL et font des binaires natifs. D'autres soutiennent que les compilateurs juste à temps peuvent faire des optimisations que les compilateurs statiques ne peuvent tout simplement pas. D'après mon expérience, cela dépend beaucoup de ce que fait votre application et de la plate-forme sur laquelle vous l'exécutez (principalement la qualité du JITer sur cette plate-forme). Il est extrêmement rare pour moi de rencontrer un scénario où .NET n'était pas assez bon .

Telastyn
la source
"interprète" `? Je pensais toujours que MS ne fournit qu'un JITter?
Doc Brown
1
@DocBrown - eh, oui - impropre de ma part. Fixation.
Telastyn
+1, pouvez-vous ajouter un peu d'explication pour mon montage afin que je puisse accepter cette réponse
vikkyhacks
Les runtimes hautes performances combinent souvent un interpréteur et un compilateur JIT (exécution en mode mixte). Je ne suis pas sûr de .NET, mais de nombreuses machines virtuelles Java utilisent cette approche.
Cyanfish
2
@busy_wait: Toutes sortes de choses. Méthode en ligne, copie de propagation, suppression de code inutile, conversion de multiplications / divisions en décalages, autres opérations arithmétiques à l'aide de readonlychamps. Les compilateurs traditionnels peuvent effectuer certaines de ces optimisations, mais uniquement lorsqu'ils peuvent être détectés par une analyse statique. En revanche, une gigue peut découvrir lors de l'exécution que (par exemple) une section de code ne fait aucun travail utile parce que les objets ou les variables qu'elle modifie ne sont référencés nulle part ailleurs. Je ne suis pas un expert de la gigue, mais c'est essentiellement une question de puissance de l'analyse dynamique vs statique.
Aaronaught
14

.NET possède un langage intermédiaire (CIL / MSIL) et des implémentations spécifiques à la plate-forme d'un runtime indépendant de la plate-forme (CLR) pour la même raison que Java. Microsoft avait l'intention que C # soit en concurrence directe avec Java, et il le fait, sur les systèmes d'exploitation que Microsoft cible (le sien).

Les avantages, même si .NET n'est pris en charge que sur les plates-formes Windows (ou d'autres systèmes d'exploitation qui ont un travail similaire à .NET comme Mono / Linux), sont similaires à Java:

  • Durée d'exécution de la mémoire gérée - Contrairement à C / C ++ non managé, les développeurs C # / VB.NET n'ont pas à se soucier de contrôler strictement la durée de vie des objets. Comme Java, le CLR possède un garbage collector qui libère automatiquement les objets du tas qui quittent la portée. Bien que cela puisse sembler mineur à quelqu'un habitué aux temps d'exécution non gérés, cela a l'avantage secondaire extrême de décourager la «magie noire» de l'arithmétique des pointeurs qui est si courante en C / C ++.
  • Indépendance de la plate-forme - Windows Vista et Windows 7 fonctionnent différemment de Windows XP. Windows 8 fonctionne toujours différemment. Les versions de Windows Mobile, y compris Windows 8 Mobile, fonctionnent à nouveau différemment. Matériel différent, architecture différente, capacités différentes. Bien que l'environnement cible ait toujours de l'importance pour un développeur .NET, la quantité de connaissances spécialisées est de loin réduite par rapport à ce qui doit être connu pour construire un programme C / C ++ compatible pour tous ces systèmes d'exploitation. AC # dev obtient beaucoup plus gratuitement.
  • Prise en charge des applications Web - Je n'ai pas encore vu une application Web client-scriptée par le serveur écrite à partir de zéro en C ++. Le serveur Web , bien sûr, Apache, ISS, ils s'exécutent généralement sur un environnement d'exécution non géré pour des raisons de vitesse / efficacité. Cependant, C ++ n'est pas un langage utilisé pour créer des applications Web. C # est (tout comme Java). Il a été conçu dès le départ pour prendre en charge la prochaine génération du paradigme ASP de Microsoft. Il s'agit d'un code conçu pour s'exécuter dans un bac à sable; quel bac à sable (le plugin ASP.NET pour ISS ou le CLR "de bureau") est relativement sans importance.
  • Indépendance vis-à-vis du langage / de l'exécution - Un compilateur C ++ prend le code source C ++ et produit le code assembleur pour une architecture de processeur en utilisant un langage machine. Pour prendre en charge une architecture et / ou un langage machine différents, un tout nouveau compilateur doit être écrit (et un tout nouvel ensemble de bibliothèques d'exécution doit être compilé). Le compilateur AC # prend le code source C # et produit CIL, que le JITer spécifique au matériel traduit en code machine. Le même JITer peut traduire n'importe quel programme CIL, quelle que soit la langue source (et il y en a plusieurs; C #, VB.NET, F # et une multitude de ports de langage "Iron" comme IronHaskell, IronRuby, IronLisp, etc.). Le même compilateur peut transformer une langue en CIL que n'importe quel JITer peut exécuter, quel que soit le matériel.
  • Concentrez-vous sur le code «correct» - Pour les développeurs C ++, il existe de nombreuses «bonnes» façons de faire quelque chose, selon ce qui est le plus important; efficacité de la mémoire, efficacité du processeur, indépendance du matériel, indépendance du système d'exploitation, etc. Le code peut être radicalement différent lorsque chacun d'eux est la priorité. C # a été conçu par un groupe qui a pris à cœur les leçons conceptuelles de Fowler et de ses collègues (qui travaillaient à réformer la conception de code au sein de la communauté C ++ en enseignant des principes orientés objet à une communauté qui y est largement passée de C), comme ainsi que les leçons pratiques tirées des langages précédents (y compris Java et son obéissance quasi fanatique à l'Objet tout-puissant, quand un bon vieux pointeur de fonction de style C ++ ferait le travail beaucoup plus proprement et ne serait pas moins objet) orienté).

Pour des raisons antitrust, MS fait attention à ne pas être vu "interférer" trop fortement dans d'autres plates-formes majeures comme Android, Mac OSX / iOS et Linux; cependant, il dispose en effet d'équipes développant pour ces trois plates-formes. Il existe une version développée par MS pour Office pour OSX, il existe de nombreuses applications, y compris les applications Office Interop pour iOS et Android, Skype (maintenant un produit Microsoft) fonctionne sur Linux, et Microsoft a même été vu contribuer au noyau Linux (principalement dans un état d'esprit de virtualisation).

KeithS
la source
1
"Je n'ai pas encore vu une application Web orientée client et scriptée par le serveur écrite à partir de zéro en C ++." - où mettez-vous les CGI d'autrefois? Mes toutes premières applications Web (aussi triviales soient-elles) étaient à 100% C. À l'époque (au milieu des années 90), il était plus facile d'écrire un .c et .h pour faire le travail standard dans cgi (les langages de script étaient juste émergeant sur la scène aussi).
hm ... CGI, CGI ... Je pense que j'en ai entendu parler, mais je suis avec KeithS, je n'en ai pas encore vu :)
DXM
@DXM l'ancien modèle de contenu dynamique consistait pour le serveur Web à bifurquer un processus et à placer les choses dans des emplacements standard (les paramètres de requête et autres sont allés dans des variables d'environnement spécifiques) - l'interface de passerelle commune. La sortie de ce processus a ensuite été renvoyée en tant que contenu. Autrefois, il était plus facile de trouver un programmeur connaissant le C ou le C ++ plutôt que le perl ou le python (et sh était très maladroit pour un tel travail).
1
Ne sous-estimez pas l'importance de la similitude avec Java. Sun venait de poursuivre MS pour son portage de la JVM et a gagné quelques points juridiques (stupidement, à mon humble avis). CIL et CLR s'en inspirent, et vous remarquerez que J # est aussi proche que possible de Java sans déclencher d'autres actions en justice. Une énorme différence est que le CLR est indépendant de la langue. Vous pouvez vraiment écrire un programme dans un mélange de C #, F # et J # si c'est ce qui est nécessaire. Essayez simplement de mélanger Java avec des bibliothèques dans d'autres langages et obtenez un programme stable.
RBerteig
1
Mais l'interopérabilité entre MSIL et le code natif est à la fois raisonnablement bien définie et fonctionne simplement. Et apparemment, il était censé fonctionner uniquement par conception et par les attitudes de la communauté des utilisateurs.
RBerteig
12

Le système d'exploitation Windows est disponible pour différents types de CPU, aujourd'hui principalement x64, x86, Intel, ARM.

CIL / CLR est indépendant de cette plate-forme matérielle - ces différences sont "résumées" par l'environnement d'exécution IL. Par exemple, un assemblage .NET compilé pour "n'importe quel CPU" peut généralement être exécuté sur Win64 en tant que processus 64 bits et Win32 en tant que processus 32 bits, sans avoir besoin de fournir différents exécutables.

De plus, le CIL permet de stocker des métadonnées dans des assemblages, ce qui n'est pas facilement possible avec des DLL natives (il est possible, bien sûr, que MS ait fait cela auparavant avec des composants COM, mais cette technologie n'a jamais été aussi facile à gérer que les composants .NET). Cela rend la création de composants logiciels beaucoup plus simple et constitue le fondement de la réflexion / introspection dans tous les langages .NET.

Doc Brown
la source
Juste pour ajouter un peu à cela, non seulement ils autorisent différents types de CPU, mais même des versions différentes (Core i3 / i5 / i7) et des fournisseurs (Intel vs AMD) dans le même type de CPU (tous les x64 par exemple) peuvent avoir différents ensembles d'instructions d'assemblage dont le compilateur JIT pourrait tirer parti
DXM
2
@DXM: et vous savez que le JIT fait réellement? Ou est-ce plutôt une chose hypothétique?
Doc Brown
Au moins un blog MSDN affirme que le compilateur JIT le fait (ou l'a fait il y a 8 ans).
@DocBrown: Évidemment, je n'ai pas de matériel de référence sous la main, mais je pensais que je me souvenais d'avoir lu quelque chose à ce sujet il y a longtemps. Merci delnan, d'avoir trouvé le lien. Cela aurait du sens puisque nous savons que les fabricants de puces aiment ajouter leurs propres instructions au-dessus du standard x86-x64, donc si la machine peut en profiter, pourquoi pas?
DXM