103.【Java Microbenchmark Harness】(二)

简介: 103.【Java Microbenchmark Harness】

3.@State (状态)【类】

源码

@State(Scope.Thread) //各个线程独自占有一个对象
@State(Scope.Benchmark)  //整个测试总共用这一个对象
package org.openjdk.jmh.samples;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.concurrent.TimeUnit;
/**
 *   @State(Scope.XXXX) 描述了这个类对象的作用域
 *   测试共享与独享的区别
 */
@Warmup(iterations = 1,time = 1,timeUnit = TimeUnit.SECONDS)  //预热次数和时间
@Measurement(iterations = 1,time = 1,timeUnit = TimeUnit.SECONDS) //测试次数和时间
public class JMHSample_03_States {
    // 所有测试线程各用各的 (独享)
    @State(Scope.Thread) //各个线程独自占有一个对象
    public static class ThreadState {  //在我们执行Benchmark的时候,他会生成一个ThreadState对象。可以被Benchmark直接使用的,也就是入参。
        volatile double x = Math.PI;
    }
    // 根据main方法,会启动4个线程去一起执行
    @Benchmark
    public void measureUnshared(ThreadState state) {  //每一个线程的入参都是不同的对象
        state.x++;
    }
    // 所有测试共享一个实列,用于测试有状态实列在多线程共享下的性能
    // 一般用来测试多线程竞争下的性能
    @State(Scope.Benchmark)  //整个测试总共用这一个对象
    public static class BenchmarkState {
        volatile double x = Math.PI;
    }
    @Benchmark
    public void measureShared(BenchmarkState state) {  //这个依然启动4个进程,但是入参都是同一个实列,竞争非常激烈
        state.x++;
    }
    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(JMHSample_03_States.class.getSimpleName())
                .threads(4)   //在执行Benchmark的时候会启动4个线程
                .forks(1)
                .build();
        new Runner(opt).run();
    }
}

4.DefaultState (默认状态)【类】

源码

@State(Scope.Thread)  //放在整体类上
package org.openjdk.jmh.samples;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.concurrent.TimeUnit;
@State(Scope.Thread)  //我们标记这个类会成为一个对象由JMH进行管理。多个线程会创建多个下面类对象
@Warmup(iterations = 1,time = 1,timeUnit = TimeUnit.SECONDS)  //预热次数和时间
@Measurement(iterations = 1,time = 1,timeUnit = TimeUnit.SECONDS) //测试次数和时间
public class JMHSample_04_DefaultState {
    double x = Math.PI;
    // 我们使用默认静态类的主要目的是:  我们不用特地的去写一个静态内部类去声明一个入参。如果没有上面的注解那么我们就需要声明一个静态内部类
    @Benchmark
    public void measure() {
        x++;
    }
    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(JMHSample_04_DefaultState.class.getSimpleName())
                .forks(1)
                .build();
        new Runner(opt).run();
    }
}

5.@Setup和@TearDown (初始化和销毁)【方法】

启动之前准备工作

// 启动Benchmark之前的准备工作
    @Setup // 必须在@State下的类中才能使用,实际上也算是@state管理对象的生命周期一部分

结束之后检查工作

// Benchmark结束之后的检查工作
    @TearDown  //必须在@State下的类中才能使用

源码

package org.openjdk.jmh.samples;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.concurrent.TimeUnit;
/**
 *   控制state 对象中的方法在什么时候执行
 *
 *   @Setup state中的方法如何被执行
 *   @TearDown state中的方法如何执行
 *   level.Trial 默认的执行策略,整个基准测试执行一次
 */
@State(Scope.Thread)  //生命默认静态类,我们可以不用进行手动传入参数
@Warmup(iterations = 1,time = 1,timeUnit = TimeUnit.SECONDS)  //预热次数和时间
@Measurement(iterations = 1,time = 1,timeUnit = TimeUnit.SECONDS) //测试次数和时间
public class JMHSample_05_StateFixtures {
    double x;
    // 启动Benchmark之前的准备工作
    @Setup // 必须在@State下的类中才能使用,实际上也算是@state管理对象的生命周期一部分
    public void prepare() {
        x = Math.PI;
        System.out.println("--------------1");
    }
    // Benchmark结束之后的检查工作
    @TearDown  //必须在@State下的类中才能使用
    public void check() {
        System.out.println("--------------2");
        // 这里使用了断言
        assert x > Math.PI : "Nothing changed?";
    }
    @Benchmark
    public void measureRight() {  //正确代码,正常执行
        x++;
    }
    @Benchmark
    public void measureWrong() {  // 这里是错误代码实列,会在Benchmark执行完毕后报错
        double x = 0;
        x++;
    }
    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(JMHSample_05_StateFixtures.class.getSimpleName())
                .forks(1)
                .jvmArgs("-ea")  //开启断言检测: assertion在一般情况下是关闭的,通过 java -ea 可以打开改功能,关闭为 -da
                .build();
        new Runner(opt).run();
    }
}

6.FixtureLevel (初始化和销毁等级)【方法】

源码

@Setup(Level.Trial)  // 与TearDown同理.启动之前会执行一次
   @TearDown(Level.Trial)  // 整个完整的基准测试之后才会执行一次
   @TearDown(Level.Iteration)  // 每轮循环完成之后才会执行一次
   @TearDown(Level.Invocation)  // 每次方法被调用都会执行一次
package org.openjdk.jmh.samples;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.concurrent.TimeUnit;
@State(Scope.Thread)  //可以免除静态内部类
@Warmup(iterations = 1,time = 1,timeUnit = TimeUnit.SECONDS)  //预热次数和时间
@Measurement(iterations = 3,time = 1,timeUnit = TimeUnit.SECONDS) //测试次数和时间
public class JMHSample_06_FixtureLevel {
    double x;
//    @Setup(Level.Trial)  // 与TearDown同理.启动之前会执行一次
//    @TearDown(Level.Trial)  // 整个完整的基准测试之后才会执行一次
//    @TearDown(Level.Iteration)  // 每轮循环完成之后才会执行一次
//     @TearDown(Level.Invocation)  // 每次方法被调用都会执行一次
    @TearDown(Level.Iteration)  // 每次方法被调用都会执行一次
    public void check() {
        System.out.println("----------1");
        assert x > Math.PI : "Nothing changed?";
    }
    @Benchmark
    public void measureRight() {
        x++;
    }
    @Benchmark
    public void measureWrong() {
        double x = 0;
        x++;
    }
    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(JMHSample_06_FixtureLevel.class.getSimpleName())
                .forks(1)
                .jvmArgs("-ea")
                .shouldFailOnError(false) //  默认是false,即使assert错误也不会让整个测试失败
                .build();
        new Runner(opt).run();
    }
}

相关文章
|
JSON 数据可视化 Java
103.【Java Microbenchmark Harness】(六)
103.【Java Microbenchmark Harness】
52 0
103.【Java Microbenchmark Harness】(六)
|
Java
103.【Java Microbenchmark Harness】(三)
103.【Java Microbenchmark Harness】
45 0
103.【Java Microbenchmark Harness】(三)
|
Java
103.【Java Microbenchmark Harness】(五)
103.【Java Microbenchmark Harness】
116 0
|
Java 编译器 BI
103.【Java Microbenchmark Harness】(四)
103.【Java Microbenchmark Harness】
72 0
|
Java 测试技术
103.【Java Microbenchmark Harness】(一)
103.【Java Microbenchmark Harness】
66 0
|
Java 测试技术
在java中使用JMH(Java Microbenchmark Harness)做性能测试
在java中使用JMH(Java Microbenchmark Harness)做性能测试
|
6天前
|
安全 Java 调度
Java编程时多线程操作单核服务器可以不加锁吗?
Java编程时多线程操作单核服务器可以不加锁吗?
20 2
|
9天前
|
存储 缓存 Java
java线程内存模型底层实现原理
java线程内存模型底层实现原理
java线程内存模型底层实现原理
|
14天前
|
缓存 Java 应用服务中间件
Java虚拟线程探究与性能解析
本文主要介绍了阿里云在Java-虚拟-线程任务中的新进展和技术细节。
|
11天前
|
Java 开发者
Java中的多线程基础与应用
【9月更文挑战第22天】在Java的世界中,多线程是一块基石,它支撑着现代并发编程的大厦。本文将深入浅出地介绍Java中多线程的基本概念、创建方法以及常见的应用场景,帮助读者理解并掌握这一核心技术。
下一篇
无影云桌面