web-dev-qa-db-ja.com

Javaコンパイル速度vs Scalaコンパイル速度

私はしばらくScalaでプログラミングをしてきましたが、それが好きですが、私が悩んでいることの1つは、プログラムのコンパイルにかかる時間です。それは小さなことのように思えますが、Javaを使用すると、プログラムに小さな変更を加え、netbeansの実行ボタンをクリックして、BOOMが実行され、scalaで時間をかけてコンパイルできます多くの時間を消費します。多くの大規模なプロジェクトでは、コンパイルに時間がかかり、Javaを使用しているときには発生しなかった必要性のために、スクリプト言語が非常に重要になると聞きました。

しかし、私は理解しているように、他のコンパイルされた言語よりも高速で、Scalaに切り替えた理由のために高速であるJavaから来ています(非常に単純な言語です)。

そこで、Scalaのコンパイルを高速化し、scalacをjavacと同じくらい高速にすることをお願いしたいと思います。

97
user405163

ScalaコンパイラはJavaよりも洗練されており、型推論、暗黙的な変換、およびはるかに強力な型システムを提供します。これらの機能は無料では提供されません。これはjavacと同じくらい高速になりますこれは、作業を行うプログラマと作業を行うコンパイラの間のトレードオフを反映しています。

とは言っても、コンパイル時間はScala 2.7からScala 2.8に大幅に改善されており、ダストが2.8に落ち着いたので改善が続くことを期待しています。 このページ は、Scalaコンパイラーのパフォーマンスを改善するための継続的な努力とアイデアの一部を文書化しています。

Martin Oderskyは彼の答えでより詳細を提供します。

55
Aaron Novstrup

Scalaコンパイラの速度)(不足)には2つの側面があります。

  1. より大きな起動オーバーヘッド

    • Scalac自体は、ロードしてjitコンパイルする必要のある多くのクラスで構成されています

    • Scalacは、すべてのルートパッケージとファイルのクラスパスを検索する必要があります。クラスパスのサイズによっては、1〜3秒余分にかかる場合があります。

    全体として、4〜8秒のスキャラックの起動オーバーヘッドが予想されます。最初に実行する場合は、ディスクキャッシュがいっぱいにならないため、より長くなります。

    スタートアップのオーバーヘッドに対するScalaの答えは、fscを使用するか、sbtで継続的にビルドすることです。 IntelliJはいずれかのオプションを使用するように設定する必要があります。そうしないと、小さなファイルであってもオーバーヘッドが不当に大きくなります。

  2. コンパイル速度が遅い。 Scalacは約500〜1000行/秒を管理します。 Javacはそれの約10倍を管理します。これにはいくつかの理由があります。

    • 型の推論は、特に暗黙的な検索を伴う場合、特にコストがかかります。

    • Scalacは型チェックを2回行う必要があります。 1回はScalaのルールに従って、2回目はJavaのルールに従って消去されます。

    • 型チェックの他に、Scala= Javaに移行するのに時間がかかる15の変換ステップがあります。

    • Scalaは通常、特定のファイルサイズごとにJavaよりも多くのクラスを生成します。特に機能的なイディオムが頻繁に使用される場合はそうです。バイトコードの生成とクラスの書き込みには時間がかかります。

    一方、1000行Scala=プログラムは2-3K行Javaプログラムに対応している可能性があるため、 2つ目は、行ごとの機能のバランスをとる必要があります。

    速度の改善に取り組んでいます(たとえば、クラスファイルを並行して生成することによる)が、この点で奇跡を期待することはできません。 Scalacはjavacほど高速になることはありません。ソリューションは、ファイルの最小限のセットのみを再コンパイルする必要があるように、適切な依存関係分析と組み合わせてfscのようなサーバーをコンパイルすることにあると思います。私たちもそれに取り組んでいます。

451
Martin Odersky

Scalaのコンパイルには、コンパイルにJavaよりも少なくとも1桁長い時間がかかることに注意してください。この理由は次のとおりです。

  1. 命名規則(ファイルXY.scalaファイルには、XYというクラスを含める必要はなく、複数のトップレベルクラスを含めることができます)。 したがって、コンパイラは、特定のクラス/特性/オブジェクト識別子を見つけるためにより多くのソースファイルを検索する必要があるかもしれません。
  2. 暗黙-暗黙の多用は、コンパイラが特定のメソッドのスコープ内の暗黙的な変換を検索し、それらをランク付けして「正しい」メソッドを見つける必要があることを意味します。 (つまり、コンパイラはメソッドの検索時に検索ドメインが大幅に増加します。
  3. 型システム-scala型システムはJavaよりもはるかに複雑であるため、より多くのCPU時間を必要とします。
  4. 型推論-型推論は計算コストが高く、javacがまったく必要としないジョブ
  5. scalacには、完全に武装した運用可能なバトルステーションの8ビットシミュレーターが含まれています。これは、GenICodeコンパイルフェーズで、マジックキーの組み合わせCTRL-ALT-F12を使用して表示できます。
40
oxbow_lakes

Scalaを使用する最良の方法は、IDEAおよびSBTを使用することです。基本的なSBTプロジェクトをセットアップします(必要に応じて行います)自動コンパイルモードで実行します(コマンド~compile)プロジェクトを保存すると、SBTはそれを再コンパイルします。

IDEAにSBTプラグインを使用し、各実行構成にSBTアクションを添付することもできます。SBTプラグインは、IDEA内のインタラクティブなSBTコンソールも提供します。

どちらの方法でも(外部で実行されるSBTまたはSBTプラグイン)、SBTは実行されたままであるため、プロジェクトの構築に使用されるすべてのクラスが「ウォームアップ」され、JIT処理され、起動オーバーヘッドが排除されます。さらに、SBTはそれを必要とするソースファイルのみをコンパイルします。これは、Scalaプログラムをビルドする最も効率的な方法です。

19
Randall Schulz

Scala-IDE (Eclipse)の最新リビジョンは、インクリメンタルコンパイルの管理がはるかに優れています。

詳細については、「 ベストScala build system? 」を参照してください。


他の解決策は、 fsc-Scala 2言語 の高速オフラインコンパイラ)を統合することです この---(ブログ投稿 に示すように) IDEのビルダー。

alt text

ただし、直接ではなくEclipseでは、 Daniel Spiewak がコメントで言及しているように:

Eclipseがすでに表面下でFSCを使用しているという理由だけで、Eclipse内でFSCを直接使用しないでください。
FSCは基本的に常駐コンパイラの上の薄い層であり、EclipseがScala=プロジェクトをコンパイルするために使用するメカニズムです。


最後に、 Jackson Davis はコメントで私に思い出させます:

sbt(シンプルビルドツール) 何らかの「インクリメンタル」コンパイルも含まれます( triggered execution を介して) 完全ではない 強化されたインクリメンタルコンパイルは、今後の0.9 sbtバージョンの作業中です。

8
VonC

fsc を使用します。これは、バックグラウンドタスクとして存在し、常にロードする必要がない高速なscalaコンパイラです。以前のコンパイラインスタンスを再利用できます。

Netbeans scalaプラグインがfscをサポートしているかどうかはわかりませんが(ドキュメントにはそう書かれています)、それを機能させることができませんでした。プラグインの夜間ビルドを試してください。

6
Denis Tulskiy

Scalaで無料のJRebelプラグインを使用できます。そのため、「デバッガで開発する」ことができ、JRebelは常に変更されたクラスをその場でリロードします。

私は、マーティン・オーデルスキー自身による暗黙の検索(コンパイラーは、曖昧さを排除するために、同じ変換に対して複数の単一の暗黙的がないことを確認する必要がある)のどこかでいくつかのステートメントを読み、コンパイラーをビジー状態に保つことができます。そのため、暗黙的な処理は慎重に行うことをお勧めします。

100%Scalaである必要はなく、同様の何かである必要がある場合は、 Kotlin を試してください。

-オリバー

3
OlliP

これは間違いなく採決されると思いますが、非常に迅速なターンアラウンドは必ずしも品質や生産性に資するとは限りません。

時間をかけて慎重に考え、実行する開発マイクロサイクルを減らしてください。良いScalaコードはより密度が高く、より本質的です(つまり、偶発的な詳細や複雑さから解放されます)。より多くの思考が必要であり、時間がかかります(少なくとも最初は)。より少ないコードでうまく進めることができます。 /テスト/デバッグサイクル。個々に少し長くなりますが、それでも生産性と作業の品質が向上します。

つまり、Scalaにより適した最適な作業パターンを探してください。

2
Randall Schulz