4

EclipseからScalaプログラムを実行すると、何か怪しいことが起こっています。Appオブジェクトを実行すると、実行に7.8秒かかります(オブジェクトのSystem.nanoTimeで計測された実際の実行時間)。コマンドラインから同じ.classファイルを実行すると、2.5秒かかります。

コンソールウィンドウの上に表示されていることに気づきました

<terminated> Run(1)[Scala Application] C:\Program Files\Java\jre6\bin\javaw.exe

これは時代に関係があるのだろうか。また、これが私のeclipse.ini設定であり、ScalaIDEページの推奨事項に従って設定しました。

-vm
C:\Program Files\Java\jre6\bin
-startup
plugins/org.eclipse.equinox.launcher_1.1.0.v20100507.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.1.R36x_v20100810
-product
org.eclipse.epp.package.java.product
--launcher.defaultAction
openFile
--launcher.XXMaxPermSize
256M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m
--launcher.defaultAction
openFile
-vmargs
-Dosgi.requiredJavaVersion=1.5
-Xms256m
-Xmx2048m
-XX:PermSize=64m
-Xss1M
-server
-XX:+DoEscapeAnalysis
-XX:+UseConcMarkSweepGC
-XX:+UseCompressedOops

この同じコードが数日前にEclipseで実行されるのに0.7秒かかっていたと99%確信しています。コードを新しいプロジェクトに貼り付けてそこから実行しようとしましたが、実行時間は変わりません。プロジェクトはグローバルなScalaコンパイラ設定を使用し、それらはすべてデフォルトに設定されています。

更新:2.9.0.1 Scalaライブラリをスワッピングして、コマンドラインとまったく同じバージョンを使用するようにしましたが、実行時間に違いはありませんでした。

また、上記のすべての-vmargsオプションを使用してコマンドラインからファイルを実行しようとしましたが、違いはありません。

何が起こっているのか、または確認する必要のある設定はありますか?ありがとう。


更新2:私は今自分で質問に半分答えました-私はさまざまな方法でコードを実行していました。しかし、ここに問題があります:

バージョン1、拡張アプリ:

object P005_V2 extends App { 
  def isDivis(x:Int, i:Int):Boolean = {
    if(i > 20) true
    else if(x % i != 0) false
    else isDivis(x, i+1)
  }
  def find(n:Int):Int = if (isDivis(n, 2)) n else find (n+2)

  val t = System.nanoTime;
  println (find (2))
  println(System.nanoTime - t)
}

Eclipseでは0.7秒、コマンドプロンプトから2.3秒かかります

バージョン2、別のオブジェクトからインスタンス化

object P005_V2 { 
  def isDivis(x:Int, i:Int):Boolean = {
    if(i > 20) true
    else if(x % i != 0) false
    else isDivis(x, i+1)
  }
  def find(n:Int):Int = if (isDivis(n, 2)) n else find (n+2)

  val t = System.nanoTime;
  println (find (2))
  println(System.nanoTime - t)
}

object Run extends App {
  P005_V2
}

Eclipseでは7.6秒、コマンドラインから2.5秒かかります

そのため、Appはコンストラクターで処理できるように設計されており、非推奨とは異なり、最適化されることを理解していますApplication。ここで起こっているように見えるprintln(find(2))のは、コンストラクターから呼び出しているため、拡張Appされないバージョンは最適化されず、時間がかかるということです。

しかし、問題は残っています。Eclipseを介した実行とコマンドラインの実行の速度に大きな違いがあるのはなぜですか。

実際、コマンドラインのJavaバージョンは0.7秒かかり、Scalaバージョンはできるだけ高速である必要があるため(Eclipseで実行されているバージョン1で示されているように)、両方のコマンドラインバージョンの実行速度が遅くなっています。

4

1 に答える 1

4

いくつかの実験の後、私は答えの95%を持っているので、自分で答えます:

Windows 7 64 ビットを実行しています。

コマンド ラインは、JAVA_HOME 変数で指定されている32 ビット JDK環境を使用しています。

Eclipse は、プロジェクトのシステム ライブラリを介して指定された64 ビット JRE環境を使用しています。Window | Preferences | Java | Installed JREs

これらのそれぞれを他のバージョンを使用するように変更すると、同様の実行時間が生成されます。

javaとは異なりscala、コマンド ラインからは、JAVA_HOME で指定されているものに関係なく、使用可能な場合は 64 ビット JVM を使用します。これは、Scala/Java の比較で混乱を招く可能性があります。

上記のバージョン 1 と 2 の間の実行時間の違いは、前述のように、バージョン 2 ではコストのかかる計算がオブジェクトのコンストラクターで実行されているためです (バージョン 1 で使用されているdelayedInt メソッドではありませんApp)。コンストラクタでコストのかかる計算や I/O を行うべきではないため、バージョン 2 は非常に間違っています。findオブジェクトからメソッドを直接呼び出すとRun、速度の異常はなくなります。

結論:

実行時間は、32 ビットまたは 64 ビットのどちらの JVM を実行しているかによって異なります。これは、環境設定に関係なく、Eclipse 内で指定されます。64 ビット バージョンを使用する場合は、コンストラクター内で重い処理を行わないように特に注意する必要があります。

実行時間 (秒):

                   Java                          Scala                         Scala - within constructor
                   JRE 64-bit     JDK 32-bit     JRE 64-bit     JDK 32-bit     JRE 64-bit     JDK 32-bit
Windows 7 64-bit   0.7            2.4            0.7            2.5            7.6            2.5
Windows XP 32-bit  n/a            13.4           n/a            14             n/a            13.1
(slower machine)
于 2011-05-31T22:15:08.090 に答える