[译]JAVA实现调度的黑魔法

61 阅读2分钟
  • 原文链接:shipilev.net/blog/2015/b… 现在我们了解了一些关于单一类型调用的基本知识,让我们看看运行时如何处理不同目标的调用。在基准测试中实现这一目标的最简单方法是修改我们的单个编码器基准测试,以分离两个编码器。​

1​@Param({"0.0", "0.1", "0.5", "0.9", "1.0"})​

8​    Random r = new Random(12345);​

10​    List<Data> ts = new ArrayList<Data>();​

11​    for (int c = 0; c < count; c++) {​

12​         byte[] contents = new byte[10];​

13​         r.nextBytes(contents);​

14​         byte id = (byte) (c < (bias * count) ? 1 : 0);​

15​         ts.add(new Data(id, contents));​

17​    Collections.shuffle(ts, r);​

18​    datas = ts.toArray(new Data[0]);​

这进一步使基准测试复杂化,因为现在我们必须决定要测量什么样的编码人员分布。应该 50/50 吗?应该 1/42 吗?事后看来,我们将引入偏置参数,它将说明 Coder 0 在分布中消耗的比率,并在 0.0、0.1、0.5、0.9 和 1.0 比率下测量基准。​

仅测量单个偏差是基准误差。它有机会将基准放在某个特定的点条件下,这可能不是真正的代码所经历的。您应该尝试戳不同的设置,看看基准测试是如何响应的。更多讨论请见 Nano trust ing the Nano time。我们的第一组实验做了 0.0、0.5 和 1.0,但是我们认为所有这些情况都以这样或那样的方式退化了,见下文。这就是为什么我们增加了更现实0.10.9

再次,让我们 “一口吃大象”,从我们已经熟悉的测试,Ref 家族开始。static_Ref 在这里不再适用,因为没有办法用静态方法选择两个编码器实现,没有别的(我们稍后会看到辅助选择器的表现)。剩下 dynamic_Interface_Ref 和 dynamic_Abstract_Ref。​

1​Benchmark                  (bias)  (count)  Mode  Cnt    Score   Error  Units​

2​Two.dynamic_Interface_Ref     0.0    10000  avgt   50   52.701 ± 0.470  us/op​

3​Two.dynamic_Interface_Ref     0.1    10000  avgt   50   57.760 ± 0.542  us/op​

4​Two.dynamic_Interface_Ref     0.5    10000  avgt   50   94.744 ± 0.035  us/op​

5​Two.dynamic_Interface_Ref     0.9    10000  avgt   50   59.046 ± 1.595  us/op​

6​Two.dynamic_Interface_Ref     1.0    10000  avgt   50   50.857 ± 0.252  us/op​

8​Two.dynamic_Abstract_Ref      0.0    10000  avgt   50   54.419 ± 1.733  us/op​

9​Two.dynamic_Abstract_Ref      0.1    10000  avgt   50   58.244 ± 0.652  us/op​

10​Two.dynamic_Abstract_Ref      0.5    10000  avgt   50   95.765 ± 0.180  us/op​

11​Two.dynamic_Abstract_Ref      0.9    10000  avgt   50   58.618 ± 0.843  us/op​

12​Two.dynamic_Abstract_Ref      1.0    10000  avgt   50   52.412 ± 0.185  us/op​