2016-10-12 93 views
0

我想为几个映射实现编写一个基准,包括一个自定义实现。我想测试它在广泛的输入上的平均表现。在一个基准测试中使用宽范围输入

由于这是我第一次使用JMH,使用@Param看起来很明显的选择。但事实证明,JMH不会在单个基准测试中使用所有这些不同的输入,但会为每组参数单独运行基准测试。

是否有一些功能应该用于它,我错过了或者只是循环输入我想在基准测试中选择的范围内的正确选项?

更新:

我实现了2个不同的基准,即给予完全相反的比较结果(注:这是特殊的地图(没有实现Map接口)使用三维坐标键)。

  1. 在基准

    @Benchmark 
    public void benchmarkGet(Blackhole bh){ 
        //8*20 different starting positions 
        for(int i = 0;i < 8 * 20;i++){ 
    
         for(int x = 0;x < 20;x++){ 
          for(int y = 0;y < 20;y++){ 
           for(int z = 0;z < 20;z++){ 
            Object value = map.get(x + offsets[i][0], y + offsets[i][1], z + offsets[i][2])); 
            bh.consume(value); 
           } 
          } 
         } 
        } 
    } 
    
  2. 获得每次只有1值,并使用状态得到不同的值,每次循环执行的输入的范围:

    @Benchmark 
    @OutputTimeUnit(value = TimeUnit.MICROSECONDS) 
    public void benchmarkGet(Blackhole bh) { 
        Object value = map.get(x + offsets[i][0], y + offsets[i][1], z + offsets[i][2])); 
        bh.consume(value); 
        x++; 
        if (x > 20) { 
         y++; 
         x = 0; 
         if (y > 20) { 
          z++; 
          y = 0; 
          if (z > 20) { 
           i++; 
           z = 0; 
           if (i >= 8*20) { 
            i = 0; 
           } 
          } 
         } 
        } 
    } 
    

哪一个是正​​确的?

+0

pls显示一些代码 – dit

+0

注意:这也是类似于这个问题:http://stackoverflow.com/questions/24496949/benchmarking-java-hashmap-get-jmh-vs-looping但它不回答我的问题:什么是正确的方式,我应该信任哪一个? – Barteks2x

回答

0

JMH基准试图非常精确地测量特定代码片段的性能。

执行速度更快的问题只能在该问题包含哪些输入时回答,因为答案可能不同。要知道平均哪个实现更快,您需要知道您必须平均进行的输入。

因此,要么说执行速度一般来说是不可能的,JMH也不会试图回答这个问题。

由于JMH认为这是一个错误的问题,并且很难提出错误的问题,所以你会遇到问题,问JMH你想要问什么问题,哪一个问题“一般”更快。

正确的实施方法实际上是使用具有不同值的Param,得到不同的基准,并且基准的结果是您从中得到的答案的范围。

在研究基准测试结果后,您的结果可能与第一种算法对某些范围内的小输入速度要快得多,但对于某些范围内的大输入速度要慢得多。你从中得出什么结论,哪一个比你的用例更快,将不得不用用例来描述用例。

+0

我知道要测试什么输入,但我不知道给出如此巨大的输入量的正确方法是什么。在这种情况下,我知道在任何真实世界的情况下,输入都将是3个整数,接近3d空间中的某个点。这正是我想要测试的。所以我一般不会测试速度,但在我的具体情况。但JMH没有标准的做法,我提出的两种方法给出了矛盾的结果。并且使用Param对少数输入进行测试需要很长时间并且不准确(数据点太少)。甚至现在我不知道哪张地图更好。 – Barteks2x

+0

@ Barteks2x测试一系列输入的问题是您可能正在测量迭代的性能。如果这很重要,迭代本身可能很重要,并且迭代是您的基准的一部分。这也可以解释为什么一种测量方法会产生不同于其他结果的结果;你正在测量迭代和.get操作。看看http://hg.openjdk.java.net/code-tools/jmh/file/ecd9e76155fe/jmh-samples/src/main/java/org/openjdk/jmh/samples/JMHSample_05_StateFixtures.java来设置州。 – Martijn

+0

所以这是我的问题:我怎样才能测量get()操作?如果我在一次“操作”中测量其中的许多数据,那么与每次操作只测量一个get()并更改下一个get()状态相比,我会得到不同的结果。 我想确定哪一个更好的唯一方法是实际测试它们在真实的东西中......但是在真实的东西中,我无法看到2d中类似地图的性能,我只能请参阅JMH中的说明(并且2d版本是我需要在性能上匹配的内容) – Barteks2x