根据行号创建ID

时间:2019-03-04 14:58:24

标签: java

我正在基于框架的应用程序上工作,我需要根据调用站点生成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,每一帧都会重新创建一次。

enter image description here 我也一直在使用StackWalker,但这带来的增加令人失望。有谁知道如何解决这个问题?

1 个答案:

答案 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);

}