.NETでCILとCLRが必要なのはなぜですか?


11

ここでこの素敵な画像を見まし。.net言語をサポートするすべてのコンパイラがソースコードをCILフォーマットに変換することを学びました。現在、Microsoftは.NET、すべてのオペレーティングシステム用のCLRを作成して、すべてのオペレーティングシステムを導入することはありません。次に、そのような中間コード形式とそのCILを実行するためのCLRを保持する理由。それは対処する頭痛ではありません。なぜマイクロソフトはこのように選んだのですか?

編集このちょっとしたアーキテクチャには価格があります。パフォーマンスが低下しますか?Javaはプラットフォームの独立性を維持するためにこれを行いますが、どのような理由で.NETがそれを行いますか?コンパイラのような単純なプレーンなCを保持しないのはなぜですか。また、新しい言語を追加する必要がある場合、どのような方法でもコンパイラーがコードをCILに変換する必要がありますが、唯一の違いはターゲット言語です。Tat's all。


3
コンパイラをCILに書く方が簡単だからです。そして、すべての言語をネイティブにするコンパイラよりも、1つのCILをネイティブコンパイラに書く方が簡単です。
-Oded

9
@ratchetfreak:これは、MSがCLRを他のプラットフォームに移植しない理由かもしれませんが、そもそもCLRを持っている理由ではないかもしれません(実際には移植が簡単になるので、引数はMSバッシングのように聞こえますが、申し訳ありません)
ドク・ブラウン

12
また、 'M $'に対するダウン投票、これは何ですか、1998年ですか?
アランB

3
Eric Lippertがこれについて議論します(3番目の段落から始めます;最初の2つの段落はRoslynについてです)。短い答えは、OdedのコメントとTelastynの答えが正しいということです。<オペレーティングシステムの数> * <言語の数>コンパイラではなく、<オペレーティングシステムの数> + <言語の数>コンパイラのみをコーディングする必要があります。
ブライアン

3
@busy_wait:参照ページにはいくつかの欠点があります。たとえば、「2つのアプリケーションの構成情報により、同じ依存アセンブリに対して異なるバインディング決定が行われる可能性があります。」オンザフライで生成すると、これらの問題を回避できます。これは、アプリの配布後にコンパイルを実際に実行する必要があることを意味します(実際、各ターゲットマシンでNGENを実行する必要があり、ディストリビュータでは実行できません)。
ブライアン

回答:


29

なぜなら、C#のCILにコンパイラを1つだけ書く必要があるからです。プラットフォームごとにCILのインタープリター(または多くの場合、ジャストインタイムコンパイラー)を作成することは、C#から(プラットフォームごとに)実行可能コードにコンパイラーを作成するのに比べて比較的簡単です。

さらに、ランタイムはCILにコンパイルされるものなら何でも処理できます。新しい言語(F#など)が必要な場合は、1つだけ記述する必要があります用のコンパイラをで、.NETがサポートするすべてのプラットフォームサポートを自動的に取得できます。

ああ、私は.NET dllを取得し、それをWindowsまたはLinuxでMono経由で再コンパイルせずに実行できます(すべての依存関係が満たされていることを前提としています)。

パフォーマンスに関しては、議論の余地があります。基本的にCILを取得してネイティブバイナリを作成する「プリコンパイラ」があります。ジャストインタイムコンパイラーは、静的コンパイラーでは不可能な最適化を行えると主張する人もいます。私の経験では、アプリケーションが何をしていて、それを実行しているプラ​​ットフォーム(そのプラットフォームでのJITerの大部分)に大きく依存します。.NETで十分ではないシナリオに遭遇することは、私にとって非常にまれです。


「通訳」 `?MSは常にJITterのみを提供すると思っていましたか?
Doc Brown

1
@DocBrown-ええ、はい-私の側では誤った呼び方をしています。修正。
テラスティン

私はこの答えを受け入れることができるように+1は、あなたが私の編集についての説明を少し追加することができ
vikkyhacks

高性能ランタイムは、多くの場合、インタープリターとJITコンパイラーを組み合わせます(混合モード実行)。.NETについてはわかりませんが、多くのJava VMはこのアプローチを使用しています。
ザリガニ

2
@busy_wait:あらゆる種類のもの。メソッドのインライン化、コピーの伝播、不要なコードの削除、乗算/除算のシフトへの変換、readonlyフィールドを使用するその他の算術演算。従来のコンパイラーはこれらの最適化の一部を実行できますが、静的分析で検出できる場合に限られます。対照的に、ジッターは実行時に、(たとえば)コードのセクションが有用な作業を行っていないことを検出できます。これは、変更するオブジェクトまたは変数が他のどこからも参照されないためです。私はジッターの専門家ではありませんが、基本的に動的分析と静的分析の力の問題です。
アーロンノート

14

.NETには、Javaと同じ理由で、中間言語(CIL / MSIL)とプラットフォーム非依存ランタイム(CLR)のプラットフォーム固有の実装があります。Microsoftは、C#がJavaと直接競合することを意図していましたが、Microsoftがターゲットとする(自社の)OS上でJavaと競合します。

.NETはWindowsプラットフォーム(またはMono / Linuxのような.NETに類似した他のOS)でのみサポートされていますが、Javaに似ています:

  • マネージメモリランタイム-アンマネージC / C ++とは異なり、C#/ VB.NET開発者はオブジェクトの有効期間を厳密に制御することを心配する必要はありません。Javaと同様に、CLRには、スコープ内のヒープ内のオブジェクトを自動的に解放するガベージコレクターがあります。これは、アンマネージランタイムに慣れている人にはささいなことかもしれませんが、C / C ++で非常に一般的なポインター演算の「ブラックマジック」を思いとどまらせるという極端な二次的な利点があります。
  • プラットフォームの独立性-Windows VistaおよびWindows 7は、Windows XPとは異なる動作をします。Windows 8の動作は異なります。Windows 8 Mobileを含むWindows Mobileバージョンの動作は再び異なります。異なるハードウェア、異なるアーキテクチャ、異なる機能。.NET開発者にとってターゲット環境は依然として重要ですが、専門知識の量は、これらのすべてのOSに対して互換性のあるC / C ++プログラムを構築するために知られているものに比べてはるかに少なくなります。AC#devは、さらに無料で入手できます。
  • Webアプリケーションのサポート-C ++でゼロから作成された、クライアント向けのサーバースクリプトWebアプリケーションはまだ見ていません。Web サーバー、確かに、Apache、ISS、それらはすべて、速度/効率の理由から、通常、すべて管理されていないランタイムに対して実行されます。ただし、C ++はWebアプリケーションの構築に使用される言語ではありません。C#は(Javaと同様)です。Microsoftの次世代ASPパラダイムをサポートするためにゼロから設計されました。これは、サンドボックスで実行するように設計されたコードです。どのサンドボックス(ISSへのASP.NETプラグインまたは "デスクトップ" CLR)は比較的重要ではありません。
  • 言語/ランタイムの独立性-C ++コンパイラは、C ++ソースコードを受け取り、1つの機械語を使用して1つのプロセッサアーキテクチャのアセンブリコードを生成します。異なるアーキテクチャやマシン言語をサポートするには、まったく新しいコンパイラーを作成する必要があります(そして、まったく新しいランタイムライブラリのセットをコンパイルする必要があります)。AC#コンパイラはC#ソースコードを取得し、CILを生成します。CILは、ハードウェア固有のJITerがマシンコードに変換します。同じJITerは、ソース言語(C#、VB.NET、F#、およびIronHaskell、IronRuby、IronLispなどの「Iron」言語ポートのホスト)に関係なく、CILプログラムを翻訳できます。同じコンパイラーは、ハードウェアに関係なく、JITerが実行できる1つの言語をCILに変換できます。
  • 「正しい」コードに焦点を当てる-C ++開発者にとって、最も重要なことに応じて、何かを行うための「正しい」方法がたくさんあります。メモリの効率、CPUの効率、ハードウェアの独立性、OSの独立性などです。これらのそれぞれが優先順位である場合、コードは大きく異なるように見えます。C#は、ファウラーと彼の同僚(C ++から大幅に移行したコミュニティにオブジェクト指向の原則を教えることでC ++コミュニティ内でコード設計を改革するために働いていた)の概念的教訓を心に留めたグループによって設計されました。以前に来た言語で学んだ実践的な教訓(Java、およびオールマイティなオブジェクトへのほぼ完全な従順を含む、古き良きC ++スタイルの関数ポインターがはるかにきれいに仕事をし、より少ないオブジェクトではない場合-指向)。

独占禁止法の理由から、MSはAndroid、Mac OSX / iOS、Linuxなどの他の主要なプラットフォームで「干渉」しすぎないように注意しています。ただし、実際にはこれらの3つのプラットフォームすべてで開発中のチームがあります。OSにはMSが開発したバージョンのOfficeがあり、iOSおよびAndroid用のOffice相互運用アプリを含む多数のアプリケーションがあり、Skype(現在はMicrosoft製品)がLinux上で実行され、MicrosoftはLinuxカーネル(主に仮想化の考え方)。


1
「C ++でゼロから作成された、クライアント向けのサーバースクリプトWebアプリケーションはまだ見ていません。」-昔のCGIはどこに置きますか?私の最初のWebアプリケーション(100%C)は100%Cでした。当時(90年代半ば)、cgiで標準作業を行うために.cと.hを書くのが簡単でした(「スクリプト」言語はシーンにも登場しています)。

hm ... CGI、CGI ...私はそれを聞いたと思いますが、私はKeithSと一緒にいますが、実際にはまだ見ていません:)
DXM

@DXMの動的コンテンツの古いモデルは、Webサーバーがプロセスを分岐し、標準の場所に配置するためのものでした(クエリパラメーターなどは特定の環境変数に入れられました)-共通ゲートウェイインターフェイス。その後、そのプロセスの出力がコンテンツとして送り返されました。昔は、perlやpythonよりもCやC ++を知っているプログラマーを見つける方が簡単でした(shはそのような作業には非常に不格好でした)。

1
Javaとの類似性の重要性を過小評価しないでください。Sunは、JVMの移植でMSを訴え、いくつかの法的ポイント(愚かにも、私見)を獲得しました。CILとCLRはそれに触発されており、J#はさらなる法的措置を引き起こすことなくJavaに可能な限り近いことに気付くでしょう。大きな違いは、CLRが言語に依存しないことです。必要であれば、C#、F#、およびJ#を組み合わせてプログラムを作成できます。Javaを他の言語のライブラリと混合して、安定したプログラムを取得してください。
RBerteig

1
ただし、MSILとネイティブコード間の相互運用性は、かなり適切に定義されており、正常に機能します。そして、どうやら設計とユーザーコミュニティの態度によって機能することが期待されていたようです。
RBerteig

12

Windows OSはさまざまなCPUタイプで利用できますが、現在は主にx64、x86、Intel、ARMです。

CIL / CLRは、そのハードウェアプラットフォームから独立しています。これらの違いは、IL実行環境によって「抽象化」されます。たとえば、「任意のCPU」用にコンパイルされた.NETアセンブリは、通常、64ビットプロセスとしてWin64上で、32ビットプロセスとしてWin32上で実行でき、異なる実行可能ファイルを提供する必要はありません。

さらに、CILを使用すると、ネイティブDLLでは簡単に実行できないアセンブリにメタデータを保存できます(もちろん、MSは以前にCOMコンポーネントでこれを行っていましたが、そのテクノロジは.NETコンポーネントほど簡単に処理できませんでした)。これにより、ソフトウェアコンポーネントの作成が非常に簡単になり、すべての.NET言語でのリフレクション/イントロスペクションの基盤となります。


これに少し追加するだけで、異なるCPUタイプだけでなく、同じCPUタイプ(すべてx64など)内の異なるバージョン(Core i3 / i5 / i7)およびベンダー(Intel対AMD)でも許可されますJITコンパイラはオフを利用することができるだろうアセンブリ命令のセット
DXM

2
@DXM:JITが実際に行うことを知っていますか?それともこれは仮説的なものですか?
ドックブラウン

少なくともMSDNブログでは、JITコンパイラーがそれを行っている(または8年前に行っていた)と主張しています

@DocBrown:明らかに参照資料は手元にありませんが、この昔のことを読んだことを思い出したと思いました。リンクを見つけてくれてありがとう、デルナン。チップメーカーは標準のx86-x64の上に独自の命令を追加することを好むので、マシンがなぜそれを利用できないのかを知っているので、それは理にかなっています。
DXM
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.