0

hi can anyone help me in this issue

I am invoking a method "add" of class "CustomeMath" now i want to know the the execution time taken by the method addMe() only (This time does not include the execution time taken by method "Invoke()" of reflection to invoke some method.).I am posting the generic code of this problem.

import java.lang.reflect.*;

public class CustomeMath{ public int addMe(int a, int b) { return a + b; }

 public static void main(String args[])
 {
    try {
      Class cls = Class.forName("CustomeMath");
      Class partypes[] = new Class[2];
       partypes[0] = Integer.TYPE;
       partypes[1] = Integer.TYPE;
       Method meth = cls.getMethod(
         "addMe", partypes);
       CustomeMath methobj = new CustomeMath();
       Object arglist[] = new Object[2];
       arglist[0] = new Integer(37);
       arglist[1] = new Integer(47);
       Object retobj 
         = meth.invoke(methobj, arglist);
       Integer retval = (Integer)retobj;
       System.out.println(retval.intValue());
    }
    catch (Throwable e) {
       System.err.println(e);
    }
 }

}

Now i want to get the execution time taken by the method "addMe()".and this time doesn't include time taken by the "invoke()" method.How do i get this time?(Remember i dont want to use the "System.currentTimeMillis();")

zaree
  • 641
  • 2
  • 6
  • 15

3 Answers3

1

If you want to measure times with some precision, you must use System.nanoTime(). Invoke as the very first line of the addMe() and invoke again as the last line, the compute the difference and print it, remember, they are nanoseconds.

If you want to measure the execution time from outside (in the main) without including the invoke() overhead, you simply can't.

System.currentTimeMillis() is very fast to execute compared to System.nanoTime(), but has a poor precision (several milliseconds), so be careful if the addMe() executes fast as the measured time could not be relevant. When you want to measure the execution time of a method that is very fast, normally you execute the method thousands in a loop and measure the total execution time with only two calls to System.nanoTime(), as the overhead imposed of the time measurement could be larger than the execution time of the method itself.

David Oliván
  • 2,717
  • 1
  • 19
  • 26
  • @David Oliván Ubieto 1stly::I can't put System.nanoTime as the very first line in my every Method (To get the execution time) and get difference (as this may be also a wish list in advance that i only know the signature and nothing else) 2ndly::My problem is remain on the same point that "i want to get the execution time taken by the method excluding the overhead taken by invoke() utility of Java Reflection" Kindly give some other direction of help. – zaree Apr 07 '11 at 06:35
  • @zaree If you invoke the method using reflection and you need to measure the execution time of the method without the invocation overhead, you have little possibilities. If we can assume the invocation overhead is much lower than execution time, use `nanoTime()` before and after the call. If you reuse the `Method` object and call the method many time, the invocation overhead could be ignored. If you can not starting putting time measurement lines in every method called (inside or outside), use a profiler as stated. – David Oliván Apr 08 '11 at 04:37
  • @zaree I think profilers impose a general overhead so you can get relative execution time between methods in order to get the methods that consume more time and absolute execution times with some precision (I'm not an expert about profiles). You can use also Java Execution Time Measurement Library (JETM) but imposes to add lines in every method, in contrast simplifies the measurements collection and printing. View also other questions [similar](http://stackoverflow.com/questions/180158/how-do-i-time-a-methods-execution-in-java). You question is not easy. – David Oliván Apr 08 '11 at 04:41
  • @David Oliván Ubieto ok let say if we use the System.currentTimeMillis() and as u say put it before and after fun() call then one problem i have face is that it shows poor accuracy.And there is a change among values if we frequently run the program.But sometime a pattern of values repeat.Can u give the reason y this happen? And normally currentTimeMilles is said to be good precision and poor accuracy. – zaree Apr 08 '11 at 08:13
  • @zaree You should use `System.nanoTime()` for precision timing. As explained in SO and others, this method gets a relative time using CPU counters and its expensive, but is very precise if you want nano precision or greater. `System.currentTimeMillins()` is very fast as gets the "clock" time of the Operating System, normally reading a global variable, but this time could be precise only at 10ms level, depending on the OS. The "clock" time has not to be accurate at this level as in .NET same occurs with `DateTime`. If you want relative times with precission, use nanoTime. – David Oliván Apr 08 '11 at 08:37
  • @zaree [Here](http://stackoverflow.com/questions/351565/system-currenttimemillis-vs-system-nanotime) you can find a discussion and the comments on the questions explain the different costs of both methods. – David Oliván Apr 08 '11 at 08:38
1

To check performance issues you would usually use profilers, then make several variations of you algorithm and compare their performance in the profiler. This is one of the main purposes of profilers, I would say it is much better bet than to try to come with a home grown solution which may or may not give you reliable results. There are quite a few of them, I have very good experience with YourKit.

And - I think a profiler is a must have tool for any serious developer regardless the programming language anyway...

Tomasz Stanczak
  • 12,796
  • 1
  • 30
  • 32
1

The only way to get the time without reflections is to call the method without reflections. This is because the method is so trivial, that attempting to monitor it will create more overhead than the actual method and give you how fast you can monitor the method rather than the speed of the method.

public static int addMe(int a, int b) {
    return a + b;
}

public static void main(String args[]) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
    Method addMe = CustomeMath.class.getMethod("addMe", int.class, int.class);
    int result = (Integer) addMe.invoke(null, 37, 47);
    System.out.println(result);

    int runs = 10000000;
    {
        long start = System.nanoTime();
        for (int i = 0; i < runs; i++)
            addMe(i, 10);
        long time = System.nanoTime() - start;
        System.out.printf("The average call time was %.1f ns%n", (double) time / runs);
    }
    {
        long start = System.nanoTime();
        for (int i = 0; i < runs; i++)
            addMe.invoke(null, i, 10);
        long time = System.nanoTime() - start;
        System.out.printf("The average call time using reflections was %.1f ns%n", (double) time / runs);
    }
}

prints

84
The average call time was 1.4 ns
The average call time using reflections was 670.1 ns

Some homework for you;

  • Can you can speculate why there is such a difference?
  • Why might you get a different result in a more realistic example?
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130