Java Resources, CPSC 331, Winter 2012

home page -  news -  syllabus -  schedule -  assignments -  tutorials -  tests -  java -  references -  Mike Jacobson


basics -  debugger (jdb) -  testing framework (JUnit) -  profiler (JRat) -  documentation (javadoc)

 Java Resources - Profiler (JRat)

Why is a Profiler Useful?

As mentioned during the lecture on testing, the kind of analysis or running times of algorithms, to be used most of the time in lecture, includes some significant simplifications. For example, we count the number of Java statements that are executed — ignoring the fact that some the time needed to execute some statements are different. A variety of factors that effect running time are ignored, as well.

Furthermore, some of the techniques that we use are only guaranteed to produce upper bounds for the worst-case running time of a program, and there these bounds are not necessarily very “tight.”

This kind of analysis is generally useful for the design stage when you are choosing an algorithm to implement (and several different algorithms, that can be used to solve the given problem, are available). It is not sufficient for software development if you are developing software that must run under significant resource restrictions; a profiler can be used to get (at least, some of) the extra information you need for this.

We will be using the profiler JRat — the “Java Runtime Analysis Toolkit” in this course.

Using JRat

One generally uses JRat in two stages:

  1. Run the program that you are interested in, with a flag set to cause timing data (and other potentially useful information) to be measured and stored.
  2. Run the “JRat Desktop” in order to see the information that has been assembled.

Using JRat at School

Suppose that you wish to see timing information for an execution of a program foo.class Then, instead of executing the command

java foo

as you usually would, you should execute the command

java -javaagent:/usr/share/java/shiftone-jrat.jar foo

This should result in a mixture of the output that you would normally see when your program is being executed, along with numerous lines of messages that can be ignored (at least, for now).

It should also result in the creation of a directory full of timing information. This will be named with the date and time when the execution of the above command started, and it will be located inside a directory called

jrat.output

which is a subdirectory of the one where you executed the above command. This subdirectory is created if it did not exist already.

By the way, I do not type in statements like the above one whenever I wish to obtain timing information. Instead — as someone who is using the tcsh command shell — I have added the following alias to my .cshrc file:

alias jprofile ’java -javaagent:/usr/share/java/shiftone-jrat.jar’

so that I can accomplish the above by typing

jprofile foo

instead. This is (for me) much less error-prone.

Users of other command shells — or operating systems — can do something similar, but the way to do it will be somewhat different.

In order to view the timing information using the JRat desktop, you should next execute the command

java -Xmx256M -jar /usr/share/java/shiftone-jrat.jar

This (normally) causes a large window to open up with a smaller “Tip of the Day” dialog window in front. It is worthwhile to read the tips that are available — they include some interesting advice about the optimization as well as information about the Jrat system — including information about how to view “hidden” statistics that are not shown by default.

Once the JRat Desktop is running, select Open from the File menu and open the file in the jrat.output directory corresponding to the program execution you wish to profile. Information about the running time of your program will be visible in the window.

Once again, I have found the above command to be too long to type reliably on a regular basis, so I have also included the alias

alias jrat ’java -Xmx256M -jar /usr/share/java/shiftone-jrat.jar’

in my .cshrc file — allowing me to open up the JRat Desktop simply by typing in

jrat

The Awful Truth: I have found, recently, that the JRat Desktop sometimes hangs: The large window opens up, with nothing inside it. I generally force the application to quit, then, and try again.

Using JRat at Home

If you have managed to download and install JUnit at home then you should find installing JRat to be reasonably straightforward. You will need to download a zip file that includes a recent version of the JRat system. We are currently using the latest version that is available, at school. You can make sure that you are using the same version at home by chooosing the file named

shiftone-jrat-1-beta1.zip

When you have extracted the files from this archive you should find that a directory named

shiftone-jrat-1-beta1

has been created, and that a file shiftone-jrat.jar is contained (along with some documentation) there. Move the file

shiftone-jrat.jar

to a reasonable place; if you move it to the directory

/usr/share/java

then you should find that you can use JRat at home, exactly as you use it at school. Otherwise you will need to make a slight change: You will need to replace the string

/usr/share/java/shiftone-jrat.jar

in the above commands with the full path to shiftone-jrat.jar on your system at home.

Comments on Optimization

Optimization is important! But it must be done selectively and with care.

Code that has been “optimized” — modified to improve efficiency — is often harder to understand and harder to maintain than the code that was optimized in order to produce it. Errors are sometimes introduced in software during optimization, too — and code that does the wrong thing, quickly, is not what we are generally trying to produce!

One of the important things that you can do with a profiler is to find out what parts of a program are being executed a lot — this is often not as obvious as you may think — so optimization can be performed, judiciously, in the places in your software where it will have the most effect.

Again, though: In general, you should optimize code only when it has been demonstrated that it is necessary to do so.

Finally, optimizing an inherently inefficient algorithm is generally not going to get you very far: If a more efficient algorithm that solves the desired problem exists, and you have implemented a (considerably) less efficient one, instead, then it is quite possible that no amount of optimization will be enough to improve your code, to the point where it is as efficient as code that would have been produced by starting with the better algorithm.

In other words, you cannot use optimization to correct a significant mistake that was made during design any more than you can use testing and debugging to do this.


Last updated:
http://www.cpsc.ucalgary.ca/~jacobs/Courses/cpsc331/W12/java/profiler.html