简体   繁体   English

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

[英]How to estimate execution time of method when it is invoked using Java Reflection

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. 我现在正在调用类“ CustomeMath”的方法“ add”,我只想知道方法addMe()所花的执行时间(此时间不包括反射到方法“ Invoke()”所花的执行时间。调用某些方法。)。我正在发布此问题的通用代码。

import java.lang.reflect.*; 导入java.lang.reflect。*;

public class CustomeMath{ public int addMe(int a, int b) { return a + b; 公共类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); } } 

} }

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();" ) 现在我想获取方法“ addMe()”花费的执行时间,而这个时间不包括“ invoke()”方法花费的时间。我如何获取这个时间?( 记住,我不想使用“ System.currentTimeMillis();”

If you want to measure times with some precision, you must use System.nanoTime() . 如果要精确地测量时间,则必须使用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. 作为addMe()第一行调用,然后作为最后一行再次调用,计算差异并打印出来,记住,它们是纳秒级的。

If you want to measure the execution time from outside (in the main ) without including the invoke() overhead, you simply can't. 如果您想从外部(在main )测量执行时间而又不包括invoke()开销,则完全不能。

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. System.nanoTime()相比, System.currentTimeMillis()执行速度非常快,但是精度较差(几毫秒),因此请小心addMe()执行速度是否很快,因为测量的时间可能addMe() 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. 当您想测量一个方法的执行时间非常快时,通常您要成千上万次地循环执行该方法,并且只需两次调用System.nanoTime()即可测量总执行时间,这是时间测量的开销可能大于方法本身的执行时间。

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. 其中有很多,我对YourKit有很好的经验。

And - I think a profiler is a must have tool for any serious developer regardless the programming language anyway... 而且-无论如何使用编程语言,对于任何认真的开发人员来说,分析器都是必备工具...

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? 为什么在更现实的示例中可能会得到不同的结果?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM