[英]Measure runtime of a method handled by bukkit.event.Listener
我需要以毫秒( #.### ms
)为单位准确测量 void 方法运行所需的时间,而测量不会影响结果。
通常我会简单地做类似的事情:
long startTime = System.nanoTime();
methodToTime();
long endTime = System.nanoTime();
long duration = (endTime - startTime); //divide by 1000000 to get milliseconds.
这不起作用,因为我的代码从不直接调用该方法; 它只定义它。
import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
public class BlockListener implements Listener {
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onPlace(BlockPlaceEvent event) {
//...
}
}
在我正在处理的这个 Minecraft Bukkit 服务器中的某些方法的上下文中,1ms 很重要,这意味着我需要高精度来测量然后优化对时间敏感的方法。
那么,在方法中添加任何代码肯定会影响方法的运行时间吗?
衡量这一点的最佳方法是什么? 谢谢,麻烦您了
使用 ProtocolLib (1.16.5) 运行 Paper/Spigot
性能测量将始终影响您的性能,这就是为什么我建议将此功能设为可切换的原因。 根据这个答案,每个方法调用System.nanoTime()
两次大约需要 200 个 CPU 时钟周期,这不是很大的开销。
但是在测量执行时间之后,您需要将其保存在某处或打印日志。 通常,I/O 操作是最昂贵的,因此最好避免在您的方法中阻塞输出。 为此,您可以利用java.util.concurrent.BlockingQueue
或线程安全管道的其他实现(如Disruptor或JCTools )并将捕获的结果记录在单独的守护线程中。
public class ListenerPerformanceAuditor implements Listener {
private final BlockingQueue<Long> executionTimeQueue;
private final Listener auditedListener;
public ListenerPerformanceAuditor(
Listener auditedListener,
BlockingQueue<Long> executionTimeQueue
) {
this.auditedListener = auditedListener;
this.executionTimeQueue = executionTimeQueue;
}
public void onPlace(BlockPlaceEvent event) {
long startTime = System.nanoTime();
auditedListener.onPlace(event);
long endTime = System.nanoTime();
long duration = (endTime - startTime); //divide by 1000000 to get milliseconds.
if(!executionTimeQueue.offer(duration)) {
// if measuring each and every request isn't necessary,
// this block can be eliminated, otherwise add error handling logic
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.