Scala在Eclipse中的执行时间

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设置,我根据Scala IDE页面上的建议进行了设置:

-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

我有99%的把握,这段代码几天前在Eclipse中运行只需要0.7秒。我尝试将代码复制到新项目并从那里运行,但运行时间没有改变。该项目使用全局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秒。

第二版本,从另一个对象实例化

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秒。
因此,我了解到该应用程序的设计是可以在构造函数中执行优化操作,而不像已弃用的Application。这里似乎发生的情况是,因为我从构造函数中调用println(find(2)),没有扩展App的版本不会被优化,所以需要更长时间。
但问题仍然存在,为什么通过Eclipse和命令行执行会有如此巨大的速度差异?
实际上,两个命令行版本都运行缓慢,因为在命令行中运行的Java版本需要0.7秒,而Scala版本应该与之一样快(正如在Eclipse中演示的版本1所示)。

дҪ е°қиҜ•иҝҮдҪҝз”ЁеёҰжңүeclipse.iniзҡ„EclipseиҝҗиЎҢеҗ—пјҲе…·дҪ“жқҘиҜҙпјҢдҪҝз”ЁJDKзҡ„dllиҖҢдёҚжҳҜJREзҡ„jarпјүпјҡhttps://dev59.com/questions/1XVC5IYBdhLWcg3w7V33#3275659 - VonC
@VonC,不确定我是否完全理解。上面的eclipse.ini始终用于启动Eclipse。我刚才尝试了一下,将其指向JDK文件夹而不是JRE,Eclipse无法加载。我也尝试过没有前两行,对运行时间没有影响。顺便说一句,我是Eclipse新手,甚至不知道ini文件的作用。 - Luigi Plinge
在链接中使用"-vm C:/Program Files (x86)/Java/jdk1.6.0_22/jre/bin/server/jvm.dll"会出现错误消息“Failed to load the JNI shared library "C:/Program Files (x86)/Java/jdk1.6.0_22/jre/bin/server/jvm.dll”。 - Luigi Plinge
该想法是看看对于运行Eclipse是否有任何影响,优化设置是否会对Scala产生影响(也就是说,如果您没有在Eclipse本身中声明任何其他JRE)。话虽如此,您的最后一次编辑更加有趣。 - VonC
1个回答

4
经过一些实验,我得到了95%的答案,所以我会自己给出:我正在运行Windows 7 64位操作系统。命令行使用32位JDK环境,由JAVA_HOME变量指定。Eclipse使用64位JRE环境,通过“Window | Preferences | Java | Installed JREs”和项目的System Library指定。更改它们中的任何一个版本都会产生类似的运行时间。与JAVA_HOME中指定的内容不同,命令行中的java将使用64位JVM(如果可用),这与scala不同,可能会导致Scala / Java比较时的混淆。上述版本1和版本2之间运行时间的差异是因为如上所述,版本2在对象的构造函数中运行昂贵的计算(而不是在Version 1中使用delayedInt方法时),版本2非常错误,因为你不应该在构造函数中进行昂贵的计算和I/O。如果直接从Run对象调用find方法,则速度异常消失。结论:运行时间将取决于您是运行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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接