设为首页 加入收藏

TOP

使用JMH进行微基准测试:不要猜,要测试!(二)
2017-09-30 17:10:00 】 浏览:639
Tags:使用 JMH 进行 基准 测试 不要
13: 2198998566,646 ops/s Iteration 14: 2201966804,597 ops/s Iteration 15: 2215531292,317 ops/s Iteration 16: 2155095714,297 ops/s Iteration 17: 2146037784,423 ops/s Iteration 18: 2139622262,798 ops/s Iteration 19: 2213499245,208 ops/s Iteration 20: 2191108429,343 ops/s

向基准中添加SFL4J

前面不是说过吗,我们要测试的用例是日志记录,那么在这个项目中我将使用SFL4J和Logback,我们向pom文件中增加依赖:

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.7.7</version>
</dependency>
<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.0.11</version>
</dependency>

然后我们增加一个logback.xml配置文件,并设置日志输出级别为INFO

<configuration>
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%highlight(%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n)</pattern>
    </encoder>
  </appender>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder><pattern>%msg%n</pattern></encoder>
  </appender>

  <root level="INFO">
    <appender-ref ref="CONSOLE" />
  </root>
</configuration>

使用maven-shade-plugin的好处是,当我们使用maven对应用进行打包的时候,所有的依赖和配置文件等都会打包到target目录下。

在日志中使用字符串连接

开始第一个微基准测试:在日志中使用字符串连接。这里我们将所需代码写到由@Benchmark注解标注的方法中,然后其他的事情就交给JMH。

这段代码中,我们创建x,y,z三个字符串变量,然后在循环中,使用字符串连接的形式将调试日志输出。代码如下:

import org.openjdk.jmh.annotations.Benchmark;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyBenchmark {

  private static final Logger logger = LoggerFactory.getLogger(MyBenchmark.class);

  @Benchmark
  public void testConcatenatingStrings() {

    String x = "", y = "", z = "";

    for (int i = 0; i < 100; i++) {
      x += i; y += i; z += i;

      logger.debug("Concatenating strings " + x + y + z);
    }
  }
}

然后还是像刚刚一样,运行这个微基准测试,并查看迭代输出。

译者注:后文将统一进行对比。

在日志中使用变量参数

这个微基准测试中,我们使用变量参数来代替字符串连接,更改代码内容如下,然后打包执行。

@Benchmark
public void testVariableArguments() {

  String x = "", y = "", z = "";

  for (int i = 0; i < 100; i++) {
    x += i; y += i; z += i;

    logger.debug("Variable arguments {} {} {}", x, y, z);
  }
}

在日志中使用If判断语句

最后一个也是最重要的一个,使用日志输出时使用isDebugEnabled()进行优化

@Benchmark
public void testIfDebugEnabled() {

  String x = "", y = "", z = "";

  for (int i = 0; i < 100; i++) {
    x += i; y += i; z += i;

    if (logger.isDebugEnabled())
      logger.debug("If debug enabled {} {} {}", x, y, z);
  }
}

微基准测试的结果

在运行三个微基准测试之后,我们将预期结果(记住,don’t guess, measure)。每秒的操作次数越多,表示性能越好。如果我们看看下表的最后一行,我们注意到使用isDebugEnabled的性能最好,使用字符串连接最糟糕。同时也能发现,在没有使用isDebugEnabled而是使用变量参数的测试结果并不差。 综合代码的可读性(较少的boilerplate code(模块化代码,也可以理解为不重要,但是又不可缺少的代码)) 。所以我会选择使用变量参数的那种形式!

String concatenation Variable arguments if isDebugEnabled
Iteration 1 57108,635 ops/s 97921,939 ops/s 104993,368 ops/s
Iteration 2 58441,293 ops/s 98036,051 ops/s 104839,216 ops/s
Iteration 3 58231,243 ops/s 97457,222 ops/s 106601
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇ThreadLocal实现方式&使用介绍—.. 下一篇跟我学Spring3(7.5):对JDBC的..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目