如何解决测量 bukkit.event.Listener 处理的方法的运行时间
我需要以毫秒 (#.### ms
) 为单位进行准确测量,即空方法运行所需的确切时间,而测量不会影响结果。
通常我会做这样的事情:
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
解决方法
性能测量总是会影响您的性能,这就是我建议将此功能设为可切换的原因。基于 this answer,每个方法调用 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
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。