web-dev-qa-db-ja.com

ScalaがCまたはC ++で実装されていなかった理由

ScalaがJavaおよび.NETでCまたはC++の代わりに実装された理由を知っていますか?ほとんどの言語はCor C++で実装されています[Erlang、Python、PHP 、Ruby、Perl] Scala Javaおよび.NETに実装されているJava =および.NETライブラリ?

[〜#〜]更新[〜#〜]

Scala Cで実装されている場合、JVMに依存するのではなく、より適切にチューニングできるため、より多くの利益が得られませんか?

28
Joshua Partogi

CとC++は言語であり、JVMは仮想マシンであり、.Netはプラットフォームであるため、質問は混乱します。 ScalaはCまたはC++で実装でき、仮想マシンのバイトコードの代わりにマシンコードを生成できます。

尋ねられた質問に答える:

ScalaはCまたはC++で実装されていません。Scalaは実際に実装されている言語であり、はるかに優れた言語だからです。

なぜそれが良いのですか?さて、- Scala言語)のOderskyの目標 について読んでください。

意図された可能性のある質問への回答:

Scalaは主にJVMバイトコードを生成します。これは、優れた移植性に加え、信頼性が高く効率的なガベージコレクター、ランタイム最適化、ジャストインタイムコンパイルなどの機能を提供するためですby JVM

最後に繰り返しますが、JVMは実行中のコードのホットスポットをマシンコードにコンパイルします。これは、CおよびC++コンパイラと同じようにコンパイルされます。

他にも利用可能な仮想マシンがありますが、Scalaの作成者であるOderskyはすでにJVMに精通しています。彼は代替としてCLRを使用するつもりでしたが、それを実現するための努力はまだ成功を収めていません。

尋ねられた/すべきだったはずの質問に答える:

マシンコードへのコンパイルは、JVMバイトコードへのコンパイルに比べて十分な利点を提供しません。

JVMに相当するものに勝るCまたはC++でマイクロベンチマークを生成することは確かに可能です。 CまたはC++で非常に最適化されたコードがJavaまたはScalaで非常に最適化されたコードよりも優れていることも事実です。ただし、長時間実行されるプログラムの場合、違いはそれほど大きくありません。

Scalaは、実行時間の短いプログラムのオーバーヘッドが大きすぎるため、特に優れたスクリプト言語ではありません。

ただし、ほとんどの場合、開発の速度とメンテナンスの容易さは、実行の速度よりも重要です。簡単に理解して変更できる非常に高いレベルのコードを書くことに人々がより関心を持っている場合、JVMによって提供されるランタイム最適化は、CまたはC++コンパイラーによって行われるコンパイル時最適化に勝ち、JVM(およびCLR )実際により速く実行されるターゲット。

したがって、Scala compilerがマシンコード実行可能ファイルであるか、またはScala programsであるかは関係ありません。マシンコードであるため、可能性速度の向上は、必ずしも速度の向上に変換されません。

そして、ちなみに、

反例を挙げましょう:Haskell。 Haskellはマシンコードを生成しますが、Haskellプログラムは、Debianの銃撃戦ではScalaの銃撃よりもうまくいきません。それを考えると、誰でも確実にScalaプログラムを直接マシンコードにコンパイルした方が高速になるでしょうか?

59

言語が世界に導入されるときに言語が直面する大きなハードルの1つは、ライブラリーの可用性です。これに対する従来の対応は、Cベースのライブラリへのアクセスを許可するCベースのFFI(外部関数インターフェース)を提供することでした。これは、さまざまな理由から理想的ではありません。

  • ライブラリがやり取りする方法には、多くの高水準言語と互換性のないさまざまな方法があります。たとえば、ライブラリがstructへのポインターを必要とする場合、ポインターなしの言語[〜#〜]および[〜#〜]なしstructsはどうですか?
  • 異なるライブラリのメモリモデルと言語の間には、しばしば解決できない、または解決可能な場合はエラーやバグが発生しやすい厳しい相互作用があります。
  • 多くのFFIのグルーコードは重要なものであり、実際には普遍的でない可能性のある知識を前提としています。 (信じようと信じまいと、すべてのプログラマーがCの教祖であるとは限りません。

これはC++ではさらに悪化します。 C++は、同じプラットフォームでコンパイラ間でC++(つまり、バイナリレベルで)と互換性がありません(!)。他の言語については言うまでもありません。

JVMをターゲットにすると、これらの問題の多くが解決され、Javaベースのライブラリの完全な巨大なスイートにアクセスできるようになります。 (非常に巨大です。スコープアウト Apache Software Foundation の初心者向けの膨大な選択肢です。)

  • Javaの呼び出しと所有権の規則は、Cの規則よりも規則的です。
  • また、JVMは、言語とライブラリの両方がインターフェイスする単一のメモリモデル(ガベージコレクションを含む)も提供します。誰が何を所有し、どこをどこでクリーンアップする必要があるかを追跡する必要はありません。ランタイムが代わりに実行します。
  • JVM上に構築されたほとんどの言語のFFIのグルーコードは存在しません(言語の舞台裏のフレームワークとして提供されているため)。たとえば、Javaライブラリにアクセスするために)Javaでプログラミングする必要はありません。Javaオブジェクトには同じ方法でアクセスしますネイティブの「オブジェクト」にアクセスします(たとえば、ClojureにはOOPの意味)の実際のオブジェクトがなく、ネイティブ言語もないため、引用符を怖がらせます)。

これらの利点に加えて、どこでも実行できるという追加の利点がありますJava実行なし再コンパイルなし(ただしwithテスト!:1回書き込み、どこでもテスト)およびJavaのかなり印象的なJITテクノロジーにアクセスできます。

CLRは同様の強みを提供しますが、IMOの弱点を追加します。これは、ほぼベンダーロックイン環境です。 (はい、私はMonoについて知っています。それはベンダーロックイン環境だとまだ思います。)

このインタビュー によると、既存のJavaインフラストラクチャとライブラリへのアクセスが主な理由でした。

... Javaは既存の言語であり、非常に厳しい制約があります。その結果、自分がやりたいと思っていた方法で多くのことを行うことができませんでした。それ以降、本質的に私の仕事の焦点がJavaをより良くすることであったとき、私は一歩下がる時だと決めました。クリーンシートから始めて、Javaよりも優れたものを設計できるかどうかを確認します。しかし、同時に、ゼロから始められないこともわかっていました。既存のインフラストラクチャに接続する必要がありました。 bootstrapライブラリ、ツール、およびそのようなものなしでは、何もかも自分自身から解放されます。

だから私はJavaとは異なる言語を設計したいと思っていても常にJavaインフラストラクチャ— JVMとそのlibraries。それがアイデアでした...

18
Jeremiah

あなたが言及する他のすべての言語、Erlang、Python、PHP、Ruby、Perl-これらはすべて作成されましたbefore Java&.NET。これらの言語の作成者がJavaまたは.NETランタイム環境が利用可能だった場合、言語を構築するときにそれらを利用した可能性があります。

もちろん、私はそれらの言語の開発者のために話すことはできないので、私は確実に.NETを使用したとは言えません。 /またはJavaビルド時に利用可能でしたが、私には良い考えのように思えます。結局のところ、Java/.NETバイトコードにコンパイルするように言語を設計することにより、 JITコンパイラ/オプティマイザの利点、言語はJava/.NETが実行されるすべてのプラットフォームで自動的に実行され、すべてのJava/.NETライブラリにアクセスできます。

10
Dean Harding

Cコードネイティブコード(マシンコード)に静的にコンパイルされます。

ScalaはJavaバイトコードに静的にコンパイルされ、必要に応じて、最適化されたネイティブコードに動的にコンパイルされます。プロセス:

Scala code --- statically-compiled-to ---> JVM byte code --- dynamically-compiled-by-JVM-Hotspot-to --->- ネイティブコード

任意の言語を構築/実行するための一般的なオプション:

  • a)ランタイムインタープリターエンジンを介してソースコードを直接解釈する
  • b)コードを静的にネイティブコードにコンパイルします(ソースなどの中間ステージを使用する可能性があります-> C->ネイティブ)。
  • c)ソースコードを静的にコンパイルして下位レベルの中間コードにして、実行時にそれを解釈する
  • d)ソースコードを静的にコンパイルして下位レベルの中間コードにし、初期解釈を使用してから、動的コンパイルと最適化手法を使用してネイティブコードに変換します。コードは、一般的な実行パスとボトルネックが見つかるまで解釈され、次に、一般的な条件下で最速の実行ができるようにコードがコンパイルされます。実行条件がこれを保証するのに十分に変化すると、再コンパイル/再調整されます

あなたの質問:「Javaが(b)C中間コードではなく(d)をJVMで使用する理由」

答え:

まず、ScalaはCよりもmuchより高いレベルの言語であり、プログラミング能力、プログラミングの容易さ、簡潔さを提供することに注意してください。ファーストクラスと高次関数、暗黙の関数、オブジェクトとしての関数、クロージャーとカリー化、高速スタック保存ループへの末尾再帰コンパイルのサポートなど、すべてがJavaよりも「1レベル高い」オブジェクト、ライブラリで(再)定義できるメソッドとしてのすべての演算子、ケースクラス、リダクション(パターンマッチング)、暗黙的な型の派生、拡張された複数の継承可能な特性と拡張されたジェネリックによる強力なポリモーフィズム、ペアとタプルの組み込み構文&短所(リストとツリー)とマップ、不変のデータ構造のサポート、メッセージのコピーとアクター間の受け渡しによる強力な「リアクティブ」な並列および並行コンピューティングのサポート、任意のドメイン固有のDSLの高度なサポート、スクリプト機能、REPL。オブジェクト指向、ポインタ管理、ガベージコレクション、文字列サポート、マルチスレッドサポート、同時実行制御、および標準APIライブラリにより、JavaはCよりも約1レベル高くなっています。

  1. パフォーマンス:高水準言語の場合、(d)は(a)-(c)よりも高速なパフォーマンスを提供します。
    直接記述され、手動で最適化されたCコードは高速です。ただし、Cに静的にコンパイルされた高水準言語は比較的低速です。 Javaデザイナーはこれをよく知っていました。彼らの現在の「ホットスポット」デザインは、桁違いにパフォーマンスを向上させます。シングルコアでは、Java HotSpotコードは人間が最適化したCと比べて平均で「50%高速」です(最高の場合は「120%高速」、最悪の場合は「30%高速」。 ')。しかし、もちろんそれはリンゴとオレンジを比較している-低レベルのコード対高レベルのコード。そして、ホットスポット最適化が使用されなかった場合、それははるかに悪いでしょう。確認するには、JVM引数を介してホットスポットのコンパイルを無効にしてください!または、ホットスポットが存在しないか未成熟だった場合のJava 1&2パフォーマンスを検討してください。または、C経由で別の言語をコンパイルしてみてください。 perlcc。したがって、上記は強力で生産的な言語にとって素晴らしい結果です。さらなる開発により、JVMが平均して手作業でコーディングされたCをすぐに上回る可能性があります。 Scalaは、平均してJavaと比べて70〜80%遅いだけです。ただし、scalaは複数のコアに強力にスケーリングします(さらなる改善が行われているため)。Javaは部分的に実行し、Cは実行しません。このような高級言語のシングルコアパフォーマンスは次のように評価されます。

    解釈<静的にコンパイル<動的にコンパイル

    マルチコアのパフォーマンス/スケーラビリティの評価:

    解釈された動的コード<静的にコンパイルされた命令コード<静的にコンパイルされた関数型/宣言型コード<動的にコンパイルされた関数型/宣言型コード

    プロセッサ速度が限界に達し、ムーアの法則によりコアの数が増加しているため、これによりscalaが優先されます。 Scalaはマルチコアで非常に高速で、将来的にはCまたはJavaの数倍の速度になる可能性があります。 Cに静的にコンパイルすることは、明らかに最速のオプションではありません。

  2. 相互運用性:広くサポートされているVMの言語は、「分離された」言語よりも言語の相互運用性が優れています。 Scala "自動的に再生" Javaクラス、インターフェイス、オブジェクトをインポートし、scalaクラス、トレイト、オブジェクトのように使用するだけです。同様のことは、Groovy、Clojure、JR​​uby、JPythonなどの他のJVM言語でも可能です。相互運用性の容易さは、理解しやすく使いやすいJavaランタイムクラス/インターフェース/オブジェクトにコンパイルするために各言語をどれだけクリーンに作成したかに依存します。それだけが「無料」で提供されます(「近く」など)。 Scalaは、JNIの後継であるJNAを介してCと相互運用します-これには多少の努力が必要ですが、ツールは時間とともにかなり効率化されました。 JNAは実際には任意の言語のコンパイルされたネイティブコードと相互運用できますが、コンパイルされたデータ型と関数の正確な構造を知っている必要があります。そうでない場合は、Cラッパーオブジェクトを使用して(または最悪の場合は、追加の「Cから他の言語へのメカニズム」を連鎖させて)、Objective C、C#、Perl、Ruby、Cobolなどと相互運用できます。

  3. 移植性:JVMは数十のオペレーティングシステムプラットフォーム/バージョンで「そのまま」実行されます。 Scalaはこれらに自動的に移植されます。例外はiOS(iPad/iPhone/iPod)です-Appleによって「技術的に」ではなく「商業的に」ブロックされています。これは、JVMの初期設計時の12年前には予想できなかったでしょう。 JVMは、Cをサポートしていないものを含む、他の何十ものサーバー、デスクトップ、モバイル、および組み込みデバイスで正常に動作します。これには、AndroidとGoogle対応のDalvik VMが含まれます(新規の50%以上)電話販売)。 確かに、Cコードは多数のプラットフォームで動作するため、「それ以上、またはおそらくそれ以上」と評価される可能性がありますJava(特に、CはObjective-Cのサブセットです)。しかし、Cは(1)、(2)、(3)のコストがかかります。もちろん、iOSのHTML5/javascript/webkit(またはObjective-C)プレゼンテーションレイヤーはリモートと相互運用できますscalaアプリ-したがって、開発者はそれを非常に行うべきです。もちろん、生産性は低下します。

  4. ツールとライブラリ:明らかに、何千もの商用およびオープンソースのJavaライブラリとツールがあり、Scalaを活用/活用できます-Cよりも多く。

  5. Security:-制御されたアプリサーバーまたはJVM環境で実行すると、セキュリティポリシーと制限に対する強力なサポートが提供されます。これは、企業環境で非常に価値のあるものになる可能性があります。

6
Glen Best

JVM/CLR

JVM(およびCLR)には、最適化とコードの移植性の点で独特の利点があります。

私が知る限り、ScalaのJVM​​バージョンのみが最新に保たれています。NETバージョンは最新ではありません。

4
Josh K

2つの無関係なものを混ぜているようです。

1つ目は、どのプログラミング言語がScala著者によってScalaを実装するために使用されていますか?)

答えは、Scala自体です。そして、これが唯一の受け入れられる答えです。なぜなら、もしあなたがこの新しい言語を発明したとしても、それを実装するために自分で使わないからです。それは?

2つ目は、Scalaで記述されたプログラムを実行するためのtarget platformとは何ですか?

ここでの選択はより興味深いものになりますが、現時点では、100%動作する唯一のターゲットはJVMです。 .NETのサポートはまだ進行中です。また、Scalaをjavacsriptにコンパイルするために作業している人もいます。理論的には、C、C++、LLVM、ネイティブコードなどにコンパイルするための「バックエンド」を追加することを妨げるものは何もありません。

JVMがプライマリプラットフォームとして選択された理由私の推測は

  • 誰もがガベージコレクションを望んでいる
  • すぐに使用できる多数の優れたライブラリ
  • Java新しいものにジャンプする準備ができているが、JVMの限界を維持している(多数のプログラマが既存のコードを別のプラットフォームに移行したくない))
3
artem

まず第一に、あなたが本当に聞きたかったのは、Scalaが厳密な方法でコンパイルされた言語ではない理由です。私はあなたに知らないことを教えてくれます。ネイティブコードよりもJVMを優先する理由はありません。

どうして?その理由は単純です。仮想化テクノロジはメモリを大量に消費し、不要なオーバーヘッドと間接的な別のレイヤーを生成します。これは、実装の問題ではありません。これは、仮想化のコアコンセプトの背後にあるロジックの問題です。あなたが何をしようとも、あなたは[〜#〜] always [〜#〜]劣った特性に終わります。特にJVMはメモリを大量に消費します。独自のランタイムコンパイラが背後で実行されているため、もはやそれほど遅くありませんが、コードの最も混雑している部分を見つけてバイナリコードに変換するには、コンパイラプロセスを実行する必要があります。

-Scala JVMベースの理由はおそらく言語の人気であったと私が考えた唯一の理由です。また、言語を実装する方が簡単であるため、この決定の背後には多少の怠惰があったと思いますクロスプラットフォームで機能するように組み立てられたように見える方法を理解するよりも、JVMを使用してください。既存のCバックエンドを使用する場合でも、JVMほど標準化されていないため、さらに多くの作業が必要です。

それが私が考えることができる理由ですが、ライセンスの問題やそれに関連する政治など、他の理由があるかもしれないことを覚えておいてください(これは、私が入りたくない汚いものです)。

0
luke1985