我正在基于框架的应用程序上工作,我需要根据调用站点生成ID,但确实非常快。
举一个简单的例子来展示基本知识;
public void test() {
if (Math.random() < 0.5) {
System.out.println(id());
} else {
System.out.println(id());
}
}
现在id()
应该提供一个唯一的ID,并且当再次运行测试时,该ID应该相同。因此无法计数。
一种简单的方法是使用行号,因此id
方法可能看起来像这样(可能必须根据调用方式更改索引):
int id() {
return (new Throwable()).getStackTrace()[1].getLineNumber();
}
出于鲁棒性,在当前应用程序中,我会基于整个堆栈生成一个id。这使得嵌套功能成为可能,并且仍会生成唯一的一致ID。问题在于它很慢,在0.007ms
的某个ID处。例如,对于文件查看器,创建ID的需求可能多达数千。
这里是我如何处理的一个示例: 切换,滑块,标签和按钮都有唯一的ID,每一帧都会重新创建一次。
答案 0 :(得分:0)
Throwable.getStackTrace()
计算整个堆栈跟踪元素。尝试通过内省直接致电Throwable.getStackTraceElement
。我的基准测试表明速度快了将近2倍。如果stacktrace更大,则差异应该更大。
public static void main(String[] args) throws Exception {
Long time = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
StackTraceElement e = new Throwable().getStackTrace()[0];
}
// 2862
System.out.println(System.currentTimeMillis() - time);
Method m = Throwable.class.getDeclaredMethod("getStackTraceElement", int.class);
m.setAccessible(true);
time = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
m.invoke(new Throwable(), 0);
}
// 1648
System.out.println(System.currentTimeMillis() - time);
}