Wednesday, January 16, 2008

Java: Using JRat under Eclipse

I'm speaking at EclipseCon 2008

Recently I was working on a Java based program that hooked into an indexing process to make modifications to the data it was indexing. In this case, it was stripping out HTML formatting and removing unnecessary whitespace. Because this was a Java app, performance was dismal. Under normal circumstances I would have gone with a platform that would provide better native support for my platform, such as C, C++, or even a scripting language like Perl would have sufficed. However that was outside of the requirements for this project.

So to improve performance, I needed a profiler to track down my performance bottlenecks. I tried the Eclipse Performance and Logging tools, only to be really disappointed with the results. And by disappointed, I mean that I received errors when running the Eclipse profiler so I couldn’t get any kind of results. So, my search for an alternative lead me to JRat.

JRat is fairly easy to use. To Launch an application for profiling, you simply append an argument to the Java VM. From Eclipse, this can be done from the Run Dialog, under the Arguments tab.

To demonstrate this, I am using the Prime Number example (not sure why I called it Factorize). The code I am using contains both the unoptimized prime number list and the optimized one. The code is below:


package com.digiassn.blogspot;

import java.util.ArrayList;
import java.util.List;

import java.util.Iterator;

public class Factorize {

private static int MAX_NUMBER = 10000;

public boolean isPrime(int number)
{
if (number == 1)
return false;

for (int x = 2; x < number; x++)
{
if ((number % x) == 0)
{
return false;
}
}

return true;
}

public List getFactors()
{
List factors = new ArrayList();

for (int x = 2; x < MAX_NUMBER; x++)
{
if (isPrime(x))
{
factors.add(x);
}
}

return factors;
}

public List getFactors2()
{
boolean [] list = new boolean[MAX_NUMBER];
List l = new ArrayList();

for (int x = 0; x < MAX_NUMBER; x++)
{
list[x] = true;
}

list[0] = false;
list[1] = false;

for (int x = 2; x < MAX_NUMBER; x++)
{
if (list[x])
{
for (int y = (x * 2); y < MAX_NUMBER; y += x)
{
list[y] = false;
}

l.add(x);
}
}

return l;
}

/**
* @param args
*/
public static void main(String[] args) {
Factorize f = new Factorize();

List l = f.getFactors();
List l2 = f.getFactors2();

for (int x = 0; x < l.size(); x++)
{
if (!((Integer)l.get(x)).equals((Integer)l2.get(x)))
{
System.out.println("Something didn't match" + l.get(x) + " " + l2.get(x));
}
}

System.out.println(l.size());
System.out.println(l2.size());
}

}


In the below screenshot, I have jRat installed under C:\Jrat.

Figure 1. Adding JRat to your Eclipse Run

That’s basically it, when you run the program, you will see a whole bunch of output from the console.

Figure 2. Console output

When run with Jrat, it will save its statistics to a file under the project folder that you will need to open in JRat in order to view your statistics. To run JRat to view statistics, you would run the following command:

java -jar shiftone-jrat.jar

Figure 3. The JRat Window.

Above is a screenshot of the file generated by JRat opened and sorted by percentage of time spent in a method. I can see that unoptimized getFactors method is where the program spent a majority of its time, were the optimized getFactors2 barely spent any time at all.

To be fair, this doesn’t offer nearly as much analysis as the Eclipse Profiler. The Eclipse Profiler has the option to test memory allocation sizes as well as execution time, and it provides some very nifty outputs, such as the ability to export class interations into UML diagrams, as shown in the below screenshot.

Figure 4. The Eclipse Profile Perspective.

While I like JRat, I did find a few things I didn’t like. The biggest one is that is isn’t a Eclipse plug-in. While this is actually a pro as well as a con, I have to admit a certain amount of lazyness on my part, and having to jump outside of Eclipse to view my results can be a little annoying. I suppose a plug-in could be built to view these results, however. Next, is the release schedule is a little inconsitent. As of this writing, the last stable release was on 2007-09-11, and before that, it was 2006-07-31. Yikes. I hope the project is still viable.

So if you get into a situation where the Eclipse profiler refuses to work with your application, you might want to give jRat a try.

6 comments:

Anonymous said...

Giving it a go now... I managed to get the eclipse profiler working 6 months ago, but since then I've had no end of problems...

Anonymous said...

Thanks for your post. It has inspired me to take a look at JRat under eclipse.

Nachiket said...

I tried the same thing but it gave me an error
Error occurred during initialization of VM
agent library failed to init: instrument
Failed to find Premain-Class manifest attribute in C:\Installer\shiftone-jrat-0.6\shiftone-jrat-0.6\dist\shiftone-jrat.jar

Do you know about it?

Anonymous said...

cntrl+c cntrl+v
if jdk 1.5 or above

java -javaagent:shiftone-jrat.jar [your java ops] [main class]
java -Xmx256M -jar shiftone-jrat.jar

Anonymous said...

I also had the error:

Error occurred during initialization of VM
agent library failed to init: instrument

Error opening zip file: shiftone-jrat.jar

To resolve the error in the "Run Configurations" / arguments panel inside eclipse I explicitly set the "VM arguments" to the full path to my installation of the shiftone-jrat.jar as follows:

-javaagent:"d:\tools\rjat\shiftone-jrat.jar"

Hope this helps someone out there.

Ankur said...

But this way JRat will give a static view of the analysis as we have not done any such instrumentation of jars. What if we want to find the bottlenecks in the code in the actual environment when the application is running. I mean configuring JRat in such a way which involves instrumentation of jars and etc....