Scala execution times in Eclipse
Asked Answered
Q

1

4

There's something fishy going on when I run Scala programs from Eclipse. I run an App object and it takes 7.8 s to run (actual execution time timed with System.nanoTime in the object). When I run the same .class file from the command line it takes 2.5 s.

I notice above the Console window it says

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

I wonder if this has any bearing on the times. Also, here are my eclipse.ini settings, which I set according to the recommendations in the Scala IDE pages:

-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

I am 99% sure this same code was taking 0.7 s to run in Eclipse a couple of days ago. I have tried pasting the code into a new project and running from there, but it doesn't change the running time. The project uses the global Scala Compiler settings and those are all set to default.

UPDATE : I have just tried swapping in the 2.9.0.1 Scala Library so that it's using the exact same version as the command line, and it made no difference to run time.

I also tried running the file from the command line with all the -vmargs options above, and it makes no difference.

Any ideas what is going on, or any settings I need to check? Thanks.


UPDATE 2 : I've half-answered the question myself now - I was running the code in different ways; but here's the problem:

Version 1, extending App :

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)
}

Takes 0.7 s in Eclipse, 2.3 s from command prompt

Version 2, instantiating from another object

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
}

Takes 7.6 s in Eclipse, 2.5 s from command line

So, I understand that App was designed so that you can do things in the constructor and they will be optimized, unlike the deprecated Application. What seems to be happening here is that because I'm calling println(find(2)) from the constructor, the version which doesn't extend Appwill not be optimized and will take longer.

But the question remains, why the huge speed differences between executing via Eclipse and the command line?

Indeed both the command line versions are running slow, because a Java version at the command line takes 0.7 s and the Scala version should be as fast (as it can be, as demonstrated by version 1 running in Eclipse).

Quaternity answered 31/5, 2011 at 0:34 Comment(4)
Did you try with an eclipse run with that eclipse.ini (specifically, with the dll of a JDK instead of a jar from a JRE): #142857Simple
@VonC, not sure if I understand fully. The eclipse.ini above is always used to start Eclipse. I tried it just now by pointing it at the JDK folder rather than JRE, and Eclipse does not load. I've also tried it without the first 2 lines and it doesn't make a difference to the run time. BTW I am an Eclipse noob so don't even really understand what the ini file does.Quaternity
Using "-vm C:/Program Files (x86)/Java/jdk1.6.0_22/jre/bin/server/jvm.dll" like in the link gives error message "Failed to load the JNI shared library "C:/Program Files (x86)/Java/jdk1.6.0_22/jre/bin/server/jvm.dll".Quaternity
the idea is to see if an optimized setting for running Eclipse has any bearing on SCala (that is if you don't have declared any other JRE within Eclipse itself). That being said, your last edit is much more interesting.Simple
Q
4

After some experimentation I have 95% of the answer so I will give it myself:

I am running Windows 7 64-bit.

The command line is using the 32-bit JDK environment, as specified by JAVA_HOME variable.

Eclipse is using the 64-bit JRE environment, specified via Window | Preferences | Java | Installed JREs and the project's System Library.

Changing each of these to use the other version produces similar running times.

java from the command line will use the 64-bit JVM when available, regardless of what is specified in JAVA_HOME, unlike scala, which can lead to confusion in Scala/Java comparisons.

The difference in running times between Versions 1 and 2 above is because, as noted, Version 2 is running the costly calculation in the object's constructor (rather than a delayedInt method when App is used in Version 1). Version 2 is very wrong, since you shouldn't do costly calculations and I/O in a constructor. If you call the find method directly from the Run object then the speed anomaly goes away.

Conclusion:

Run times will depend on whether you are running the 32-bit or 64-bit JVM, and this is specified within Eclipse regardless of your environment settings. If using the 64-bit version you need to be especially careful not to do heavy processing within a constructor.

Running times (seconds):

                   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)
Quaternity answered 31/5, 2011 at 22:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.