如何使用Java Reflection调用方法的执行时间

时间:2011-04-07 05:46:50

标签: java reflection time execution

嗨,任何人都可以帮我解决这个问题

我正在调用类“CustomeMath”的方法“添加”现在我想知道方法addMe()所花费的执行时间(这次不包括方法“Invoke()”所用的执行时间)反射调用某种方法。)。我发布了这个问题的通用代码。

  

import java.lang.reflect。*;

     

public class CustomeMath {       public int addMe(int a,int b)        {           返回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);
    }
 }
     

}

现在我想获得方法“addMe()”所花费的执行时间。这次不包括“invoke()”方法所花费的时间。我怎么得到这个时间?(记住我不想使用“System.currentTimeMillis();”

3 个答案:

答案 0 :(得分:1)

如果要精确测量时间,必须使用System.nanoTime()。作为addMe()的第一行调用并再次调用作为最后一行,计算差异并打印它,记住,它们是纳秒。

如果您想从外部(main)测量执行时间而不包括invoke()开销,则根本不能。

System.currentTimeMillis()相比,

System.nanoTime()的执行速度非常快,但精度很差(几毫秒),因此如果addMe()执行速度很快,请小心,因为测量的时间不能相关。当您想要测量非常快的方法的执行时间时,通常在循环中执行数千个方法并仅用两次调用System.nanoTime()来测量总执行时间,作为时间测量的开销可能大于方法本身的执行时间。

答案 1 :(得分:1)

要检查性能问题,您通常会使用分析器,然后对您的算法进行多种变体处理,并在分析器中比较它们的性能。这是剖析器的主要目的之一,我想说,尝试使用可能会或可能不会给您可靠结果的本土解决方案更好。其中有不少,我对YourKit有很好的经验。

并且 - 我认为无论编程语言如何,对于任何认真的开发人员来说,分析器都是必备工具......

答案 2 :(得分:1)

获得没有反射的时间的唯一方法是在没有反射的情况下调用方法。这是因为该方法非常简单,尝试监视它会产生比实际方法更多的开销,并且为您提供监视方法的速度,而不是方法的速度。

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);
    }
}

打印

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

为你做一些功课;

  • 你能猜出为什么会有这样的差异吗?
  • 为什么你会在一个更现实的例子中得到不同的结果?