tags:

views:

10002

answers:

15

It seems like it should be simpler than it is to get a method's execution time. Is there a Timer utility class for things like timing how long a task takes, etc? Most of the searches on Google return results for timers that schedule threads and tasks, which is not what I want.

+9  A: 

This probably isn't what you wanted me to say, but this is a good use of AOP. Whip an proxy interceptor around your method, and do the timing in there.

The what, why and how of AOP is rather beyond the scope of this answer, sadly, but that's how I 'd likely do it.

Edit: Here's a link to Spring AOP to get you started, if you're keen. This is the most accessible implementation of AOP that Iive come across for java.

Also, given everyone else's very simple suggestions, I should add that AOP is for when you don't want stuff like timing to invade your code. But in many cases, that sort of simple and easy eapproach is fine.

skaffman
+8  A: 

I go with the simple answer. Works for me.

long startTime = System.currentTimeMillis();

doReallyLongThing();

long endTime = System.currentTimeMillis();

System.out.println("That took " + (endTime - startTime) + " milliseconds");

It works quite well. The resolution is obviously only to the millisecond, you can do better with System.nanoTime(). There are some limitations to both (operating system schedule slices, etc.) but this works pretty well.

Average across a couple of runs (the more the better) and you'll get a decent idea.

MBCook
Actually, System.currentTimeMillis() is only accurate above 15ms. For really low values it can't be trusted. The solution for this (as mentioned) is System.nanoTime();
Steve g
Ok, I was about to accept this as the official answer until I read Steve g's comment. Great tidbit, Steve!
Ogre Psalm33
nanoTime() does not guarantee accuracy better than currentTimeMillis, but many JVM implementations do have better accuracy with nanoTime.
James Schek
+2  A: 

If you want wall-clock time

long start_time = System.currentTimeMillis();
object.method();
long end_time = System.currentTimeMillis();
long execution_time = end_time - start_time;
David Nehme
+11  A: 

There is always the old-fashioned way:

final long startTime = System.nanoTime();
final long endTime;
try {
  methodToTime();
} finally {
  endTime = System.nanoTime();
}
final long duration = endTime - startTime;
Diastrophism
actually, its "new-fashioned" because you used nanoTime, which wasn't added until java5
John Gardner
This (or using System.currentTimeMillis()) seems to be the way it's usually done in Java...that I've seen anyway. It still mildly suprises me that there's no spiffy built-in class, like Timer t = new Timer(); String s = t.getElapsed(format); etc...
Ogre Psalm33
nanoTime does not guarantee accuracy better than currentTimeMillis(), though it usually does. http://forums.sun.com/thread.jspa?messageID=9460663 and http://www.simongbrown.com/blog/2007/08/20/millisecond_accuracy_in_java.html
James Schek
Of course, it's always important to remember the pitfalls of micro-benchmarking, such as compiler/JVM optimizations that may distort the result =8-)
Yuval
There is no need for a finally block as endTime won't be used if an exception is thrown.
Peter Lawrey
A: 
long startTime = System.currentTimeMillis();
// code goes here
long finishTime = System.currentTimeMillis();
long elapsedTime = finishTime - startTime; // elapsed time in milliseconds
rodey
+3  A: 

I basically do variations of this, but considering how hotspot compilation works, if you want to get accurate results you need to throw out the first few measurements and make sure you are using the method in a real world (read application specific) application.

If the JIT decides to compile it your numbers will vary heavily. so just be aware

luke
+1  A: 

There are a couple of ways to do that. I normally fall back to just using something like this:

long start = System.currentTimeMillis();
// ... do something ...
long end = System.currentTimeMillis();

or the same thing with System.nanoTime();

For something more on the benchmarking side of things there seems also to be this one: http://jetm.void.fm/ Never tried it though.

Horst Gutmann
+1  A: 

As "skaffman" said, use AOP OR you can use run time bytecode weaving, just like unit test method coverage tools use to transparently add timing info to methods invoked.

You can look at code used by open source tools tools like Emma (http://downloads.sourceforge.net/emma/emma-2.0.5312-src.zip?modtime=1118607545&big_mirror=0). The other opensource coverage tool is http://prdownloads.sourceforge.net/cobertura/cobertura-1.9-src.zip?download.

If you eventually manage to do what you set out for, pls. share it back with the community here with your ant task/jars.

anjanb
+11  A: 

Use a profiler (JProfiler, Netbeans Profiler, Visual VM, Eclipse Profiler, etc). You'll get the most accurate results and is the least intrusive. They use the built-in JVM mechanism for profiling which can also give you extra information like stack traces, execution paths, and more comprehensive results if necessary.

When using a fully integrated profiler, it's faily trivial to profile a method. Right click, Profiler -> Add to Root Methods. Then run the profiler just like you were doing a test run or debugger.

James Schek
This was also a great suggestion, and one of those "duh" light-bulb moments for me when I read this answer. Our project uses JDeveloper, but I checked, and sure enough, it's got a built-in profiler!
Ogre Psalm33
It's times like these I like to rub my bloated, overweight, slow IDE in the faces of the emacs elitists. :-)
James Schek
+4  A: 

JAMon API is a free, simple, high performance, thread safe, Java API that allows developers to easily monitor the performance and scalability of production applications. JAMon tracks hits, execution times (total, avg, min, max, std dev), and more.

http://jamonapi.sourceforge.net/

download : http://sourceforge.net/project/showfiles.php?group_id=96550

Mike Pone
+1  A: 

We are using AspectJ and Java annotations for this purpose. If we need to know to execution time for a method, we simple annotate it. A more advanced version could use an own log level that can enabled and disabled at runtime.

public @interface Trace {
  boolean showParameters();
}

@Aspect
public class TraceAspect {
  [...]
  @Around("tracePointcut() && @annotation(trace) && !within(TraceAspect)")
  public Object traceAdvice ( ProceedingJintPoint jP, Trace trace ) {

    Object result;
    // initilize timer

    try { 
      result = jp.procced();
    } finally { 
      // calculate execution time 
    }

    return result;
  }
  [...]
}
This is informative. Similar to skaffman's answer, but with an actual example--nice!
Ogre Psalm33
A: 

Of course I should mention that most Java loggers give you timing for free too. Even org.apache.commons.logging.impl.SimpleLog can write timing information into the log file, so just add some log statements and you've got timing. See for example the Commons Logging guide.

Ogre Psalm33
+2  A: 

Just a small twist, if you don't use tooling and want to time methods with low execution time: execute it many times, each time doubling the number of times it is executed until you reach a second, or so. Thus, the time of the Call to System.nanoTime and so forth and the accuracy of System.nanoTime does affect the result much. Of course, the caveats about using the wall clock apply:, influences of JIT-compilation, multiple threads / processes etc.

    int runs = 0;
    int runsPerRound = 10;
    long begin = System.nanoTime();
    long end;
    do {
        for (int i=0; i<runsPerRound; ++i) timedMethod();
        end = System.nanoTime();
        runs += runsPerRound;
        runsPerRound *= 2;
    } while (1000000000L < end-begin);
    System.out.println("Time for timedMethod() is " + 
        0.000000001 * (end-begin) / runs + " seconds");
hstoerr
+1  A: 

You might also want to look at the Apache Commons Lang StopWatch class. A simple but useful utility class.

kaliatech