4

hopefully this is an easy and quick question. I recently developed a CPU intensive java application in Netbeans. It uses A* pathfinding tens of thousands of times per second to solve a tiles matching game. The application is finished, and it runs pretty fast (I've been testing in netbeans the whole time). I've clocked it at 700 attempts per second (each attempt is probably 20 or so pathfinds). When I build the project it creates a jar, and I can run this outside of netbeans. If I use the command line (Windows 7), and use java -jar theFile.jar, I clock it at 1000 attempts per second. This is understandable since the IDE was probably using a bit of cpu power and holding it back (My application is multicored, you can set the number. I usually use 3/4 so it doesnt slow my system too much). Now, the confusing part. Obviously I don't want the user to have to use the command line every time they want to run this application on windows. They should just be able to click the jar. The problem is that when I double click the jar file, the program runs at a sickly 300 attempts per second!!

Why on earth would these three ways of running the exact same program, all else being constant, have such a massive impact on performance? Is my fix to create a script to run the .jar by command line, or do you guys recognize what's going on here? Thanks very much!

Edit: New Information

I made a batch file with the command: java -jar theFile.jar When this is executed, it runs at the same speed as it would if I ran it in the console (so, 1000 att/sec)

However, I also made an executable with a simple c++ program. The program had just a couple lines, and was System("java -jar theFile.jar"); and return 0;. Unbeleivably, this runs at the speed of double clicking the jar file, about 300att/sec. How bizarre! It could very well be different IDE parameters, but i'm not sure how to check the default system parameters, or how to modify them for this particular jar.

user2045279
  • 691
  • 1
  • 6
  • 16
  • Have you tested performance with your suggested script file? It might be interesting to see if it is the same as running the JAR from the command line. – Code-Apprentice Feb 28 '13 at 01:13
  • This may have something to do with the specific JVM (or even JVM args) that the operating system is providing when a jar file is double clicked. When ran from the command line, you have control over these things. Perhaps you could package your application with a batch file to launch it? –  Feb 28 '13 at 01:13
  • I added some new findings in the main post. More confusion overall, but it's probably what Ron said about JVM arguments – user2045279 Feb 28 '13 at 02:24
  • How are you measuring the speed? For how long does the application run? – thkala Feb 28 '13 at 02:45
  • When the program gets stumped on a particular board of tiles (there may be very few way to solve it), it will display on the GUI every 100 tries it makes. So Ill use a stopwatch and time how long it takes to get to 1000. I test all of these on the same exact board. Its visually apparent which ones are faster even without the stopwatch. It runs as long as I choose, or until it solves the board (unlikely in this case). The speed remains constant – user2045279 Feb 28 '13 at 03:28

1 Answers1

3

You may be running into the differences between the client and server versions of the HotSpot VM. From this article:

  • On platforms typically used for client applications, the JDK comes with a VM implementation called the Java HotSpot™ Client VM (client VM). The client VM is tuned for reducing start-up time and memory footprint. It can be invoked by using the -client command-line option when launching an application.

  • On all platforms, the JDK comes with an implementation of the Java virtual machine called the Java HotSpot Server VM (server VM). The server VM is designed for maximum program execution speed. It can be invoked by using the -server command-line option when launching an application.

I'm guessing that clicking the jar file may be invoking the client VM, unless you set the -server flag. This article provides some more details:

What's the difference between the -client and -server systems?

These two systems are different binaries. They are essentially two different compilers (JITs)interfacing to the same runtime system. The client system is optimal for applications which need fast startup times or small footprints, the server system is optimal for applications where the overall performance is most important. In general the client system is better suited for interactive applications such as GUIs. Some of the other differences include the compilation policy,heap defaults, and inlining policy.

Where do I get the server and client systems?

Client and server systems are both downloaded with the 32-bit Solaris and Linux downloads. For 32-bit Windows, if you download the JRE, you get only the client, you'll need to download the SDK to get both systems.

For 64-bit, only the server system is included. On Solaris, the 64-bit JRE is an overlay on top of the 32-bit distribution. However, on Linux and Windows, it's a completely separate distribution.

I would like java to default to -server. I have a lot of scripts which I cannot change (or do not want to change). Is there any way to do this?

Since Java SE 5.0, with the exception of 32-bit Windows, the server VM will automatically be selected on server-class machines. The definition of a server-class machine may change from release to release, so please check the appropriate ergonomics document for the definition for your release. For 5.0, it's Ergonomics in the 5.0 Java[tm] Virtual Machine.

Should I warm up my loops first so that Hotspot will compile them?

Warming up loops for HotSpot is not necessary. HotSpot contains On Stack Replacement technology which will compile a running (interpreted) method and replace it while it is still running in a loop. No need to waste your applications time warming up seemingly infinite (or very long running) loops in order to get better application performance.

Andrew Mao
  • 35,740
  • 23
  • 143
  • 224
  • Sorry for the delay, midterms at university :(. I tried to add the -server flag in Netbeans under Project properties, build, compiler, additional compiler options. When it tries to build, it says it does not recognize the -server flag. Any ideas on how to set the -server flag? – user2045279 Mar 02 '13 at 21:53
  • It should be a VM option, not a compiler option. See http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html. Also, you may have to "warm up" your code to get the full performance immediately under server; see http://stackoverflow.com/questions/1481853/technique-or-utility-to-minimize-java-warm-up-time – Andrew Mao Mar 02 '13 at 22:07
  • Sorry for the delay. I'll try that, thank you again for your help – user2045279 Mar 14 '13 at 13:02