java 如何在方法调用周围 Package 计时方法

vd8tlhqk  于 2023-09-29  发布在  Java
关注(0)|答案(4)|浏览(97)

如何将计时方法 Package 在方法调用周围,有没有简单的方法来 Package StopWatch

for (Foo foo : foos) {
    StopWatch sw = new StopWatch();
    sw.start();
    someService.processFoo(foo);
    sw.stop();
    log.trace("saved foo in {} msecs", sw.getTotalTimeMillis());
}
ghg1uchk

ghg1uchk1#

如果你的服务实现了一个接口,你可以使用一个代理来实现这个接口:

public class TimerProxy {
    private final Object delegate;
    
    public TimerProxy(Object delegate) {
        this.delegate = delegate;
    }

    public <T> T getInterface(Class<T> intf) {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        Object proxy = Proxy.newProxyInstance(loader, new Class<?>[] {intf},
                (pxy, method, args) -> {
            return execute(method, args);
        });
        return intf.cast(proxy);
    }

    private Object execute(Method method, Object[] args) {
        StopWatch sw = new StopWatch();
        sw.start();
        try {
            return method.invoke(delegate, args);
        } finally {
            sw.stop();
            log.trace("Method call {} in {} msecs",
                    method.getName(), sw.getTotalTimeMillis());
        }
    }
}

如果你有一个实现接口Service的服务,你会做:

Service service = ...;
Service proxy = new TimerProxy(service).getInterface(Service.class);

然后可以使用proxy而不是service来记录方法调用的持续时间。

aurhwmvo

aurhwmvo2#

for (Foo foo : foos) {
    long start = System.currentTimeMillis();
    someService.processFoo(foo);
    long delta = System.currentTimeMillis() - start);
    log.trace("saved foo in {} msecs", delta);
}

请注意,如果您主要是想测量java代码的运行速度,那么这并不是那么简单。你会得到非常误导的数字,特别是对于相对较快的任务。如果这是你想做的,read this tutorial on how to use JMH

91zkwejq

91zkwejq3#

将方法调用 Package 为runnable,并为希望记录的每个任务创建一个类似logTaskTime的实用程序作为methodWrapper

public static void main(String[] args) {
        Foo[] foos = new Foo[0];
        for (Foo foo : foos) {
            Runnable runnable = () -> {/*someService.processFoo(foo);*/};
            logTaskTime(runnable);
        }
    }

    private static void logTaskTime(Runnable runnable) {
        StopWatch sw = new StopWatch();
        sw.start();
        runnable.run();
        sw.stop();
        System.out.println(sw.getTime());
       // log.trace("saved foo in {} msecs", sw.getTotalTimeMillis());
    }

我希望像其他答案中提到的那样,这不是被用来衡量java代码的性能。

a5g8bdjr

a5g8bdjr4#

您可以编写一个执行任务并测量执行时间的 Package 器

public class TaskTimer {

  private static final Logger LOGGER = LoggerFactory.getLogger(TaskTimer.class);

  private final Runnable taskToMeasure;

  public TaskTimer(Runnable taskToMeasure) {
    this.taskToMeasure = taskToMeasure;
  }

  public void doTask() {
    long start = System.nanoTime();
    this.taskToMeasure.run();
    long end = System.nanoTime();
    long millis = TimeUnit.NANOSECONDS.toMillis(end - start);
    LOGGER.trace("Task finished in {} millis", millis);
  }
}

然后在其中 Package 任何任务:

TaskTimer task1 = new TaskTimer(() -> someService.processFoo(foo));
task1.doTask();
TaskTimer task2 = new TaskTimer(() -> otherServide.processBar(bar));
task2.doTask();
TaskTimer task3 = new TaskTimer(() -> thirdService.processFooBar(fooBar));
task3.doTask();
//etc.

请记住,这是一种非常简单和天真的测量执行时间的方法,所以它不会绝对准确。

相关问题