当前位置: 首页 > 知识库问答 >
问题:

如何在jmh基准测试中生成方法?

边明煦
2023-03-14

我使用 jmh(http://openjdk.java.net/projects/code 工具/jmh/ ) 来基准测试一些方法。此外,我有一组参数,我想用它们作为参数来运行此方法。是否可以为每个特定参数值生成一个方法(带有@GenerateMicroBenchmark注释)?

现在我使用类似的实现,但不太方便,因为我必须手动编写很多统一的代码:

interface State {
    int action();
    void prepare();
}

class Method {
    ...;
    toString() { return "State1_" + param; }
}

{
    Method[] states;
    curState = -1;
    count = 0;
    int[] params = {1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000};
    for (int param: params) {
      states[count++] = new Method(param);
    }
}

@Setup(Level.Invocation)
public void prepareState() {
  if (curState != -1) {
    states[curState].prepare();
  }
}

@GenerateMicroBenchmark
public int param_1000() {
    curState = 0;
    return states[curState].action();
}

@GenerateMicroBenchmark
public int param_2000() {
    curState = 1;
    return states[curState].action();
}

@GenerateMicroBenchmark
public int param_3000() {
    curState = 2;
    return states[curState].action();
}
...
@GenerateMicroBenchmark
public int param_12000() {
    curState = 11;
    return states[curState].action();
}

共有1个答案

郭博涉
2023-03-14

如果没有一些严重的损坏,基准通常不会被重用。我见过的试图简化基准的大多数尝试都超出了他们的想象。例如,在这里使用数组可能会抵消纳米基准测试的结果(例如,如果action()很小)。<代码>级别。调用通常也是一个坏主意,正如其Javadoc中所述。

底线是,仅仅因为API允许某些用法,并不一定意味着您应该使用它。以下是您应该做的:

@State(Scope.Thread)
class MyBenchmark {
    Method[] states;

    @Setup
    public void setup() {
        int[] params = {1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000};
        int count = 0;
        for (int param: params) {
            states[count++] = new Method(param);
        }
    }

    int doWork(int idx) {
        states[idx].prepare();
        return states[idx].action();
    }

    @GenerateMicroBenchmark
    public int param_1000() {
       doWork(0);
    }

    ...

    @GenerateMicroBenchmark
    public int param_12000() {
       doWork(11);
    }
}

...甚至:

@State(Scope.Thread)
class MyBenchmark {
    Method p1000, p2000, ..., p12000;

    @Setup
    public void setup() {
        p1000 = new Method(p1000);
        p2000 = new Method(p2000);
        ...
        p12000 = new Method(p12000);
    }

    @GenerateMicroBenchmark
    public int param_1000() {
       p1000.prepare();
       return p1000.action();
    }

    ...

    @GenerateMicroBenchmark
    public int param_12000() {
       p12000.prepare();
       return p12000.action();
    }
}

另一种方法是接受来自外部的参数,并使用JavaAPI处理参数。为了举例说明:

@State(Scope.Thread)
class MyBenchmark {
    final int param = Integer.getInteger("param", 1000); 

    Method m;

    @Setup
    public void setup() {
        m = new Method(param);
    }

    @GenerateMicroBenchmark
    public int work() {
       m.prepare();
       return m.action();
    }

     public static void main(String[] args) throws RunnerException {
         Options opts = new OptionsBuilder()
                 .include(".*")
                 .jvmArgs("-Dparam=2000")
                 .build();

         RunResult runResult = new Runner(opts).runSingle();
         Result result = runResult.getPrimaryResult();

         System.out.println();
         System.out.println("API replied benchmark score: " + result.getScore() + " " + result.getScoreUnit() + " over " + result.getStatistics().getN() + " iterations");
     }
}
 类似资料:
  • 我还没能找到任何真正能回答我问题的答案,所以就这样吧。 我编写了一个Java库,我希望使用一个独立的Java项目来执行基准测试,该项目将JMH作为依赖项。我能够编写一个执行基准测试的基准测试方法,但是这还不够详细,不能满足我的需要。我想知道图书馆的哪些方法占用的时间最多。通过这种方式,我更好地了解了可能的瓶颈,以及从哪里开始优化我的库。 这意味着我希望有一个详细的树报告,其中显示了底层方法调用以及

  • 请阅读此问题的最新编辑。 问题:我需要编写一个正确的基准测试,以将使用不同线程池实现(也来自外部库)使用不同的执行方法的不同工作与使用其他线程池实现的其他工作以及没有任何线程的工作进行比较。 例如,我有24个任务要完成,10000个随机字符串处于基准状态: 和两个状态作为表示工作的内部类(string concat。)和ExecutorService的设置和关闭: 更严格的问题是:如何编写正确的基

  • 在我的场景中,基准测试中的方法应该在一个线程中按顺序运行并按顺序修改状态。 例如,有一个

  • 我正在使用向服务器发送REST请求的自定义Java库为HTTP服务器编写性能测试。在开始时,我正在执行数据准备阶段,以便获得一个要向服务器发送请求的对象列表。 现在,问题是,我可以使用注释测试可以注入基准函数的参数列表: 问题是,我希望通过Java参数列表实现同样的效果,并避免对它们进行迭代。你能告诉我怎么做吗?

  • 我使用JMH对DOM解析器进行基准测试。我得到了非常奇怪的结果,因为第一次迭代实际上比后面的迭代运行得更快 有人能解释为什么会这样吗?此外,百分位数和所有数字意味着什么?为什么在第三次迭代后它开始变得稳定?一次迭代是否意味着整个基准测试方法的一次迭代?下面是我正在运行的方法

  • 受另一个关于堆栈溢出的问题的启发,我编写了一个微型基准来检查,什么更有效: 有条件地检查零除数或 捕获和处理 下面是我的代码: 我对JMH完全陌生,不确定代码是否正确。 我的基准是正确的吗?你看到任何错误吗? 旁白:请不要建议询问https://codereview.stackexchange.com.对于Codereview,代码必须已按预期工作。我不确定这个基准是否能按预期工作。