我目前正在使用byte buddy添加一些简单的逻辑,以每个线程为单位统计总的方法调用次数。
对于咨询仪器,我的思路是这样的。
@Advice.OnMethodEnter
static void handle() {
MethodCounter.increment();
}
在... MethodCounter#increment
我有一个非常简单的 ThreadLocal
计数器,而计数器本身只是递增一个整数。
public class MethodCounter {
final ThreadLocal<Counter> threadCounter = new ThreadLocal<Counter>();
public static void increment() {
threadCounter.get().increment();
}
... and some other logic that ensures that the Counter is initialized for the current thread ...
}
当使用JMH对这个新逻辑进行基准测试时,我注意到在一个样本工作流(包含紧缩循环)中,性能下降了大约30%。 其中大部分似乎是由于 ThreadLocal
-- 如果我改成去掉 ThreadLocal.get()
和硬编码 increment()
来增加一个静态的 Counter
,对性能影响很小。
有没有一种性能更高的方法,在保持每线程隔离的同时,用字节伙伴来完成这个任务?
一旦一个类被工具化,Byte Buddy就真的没戏了。
为了避免昂贵的线程本地,你可以尝试使用 无锁 它以线程为基础使用并发映射,可以有更好的表现。一般来说,线程-locals然而有些昂贵,特别是当你经常查找的时候,也没有什么好办法。