标签: jmh

为什么StringBuilder#append(int)在Java 7中比在Java 8中更快?

在研究使用和将整数原语转换为字符串的一些小辩论时"" + n,Integer.toString(int)我编写了这个JMH微基准测试:

@Fork(1)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
public class IntStr {
    protected int counter;


    @GenerateMicroBenchmark
    public String integerToString() {
        return Integer.toString(this.counter++);
    }

    @GenerateMicroBenchmark
    public String stringBuilder0() {
        return new StringBuilder().append(this.counter++).toString();
    }

    @GenerateMicroBenchmark
    public String stringBuilder1() {
        return new StringBuilder().append("").append(this.counter++).toString();
    }

    @GenerateMicroBenchmark
    public String stringBuilder2() {
        return new StringBuilder().append("").append(Integer.toString(this.counter++)).toString();
    }

    @GenerateMicroBenchmark
    public String stringFormat() {
        return String.format("%d", this.counter++);
    }

    @Setup(Level.Iteration)
    public void prepareIteration() {
        this.counter = 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用默认的JMH选项运行它,我的Linux机器上都存在两个Java VM(最新的Mageia 4 64位,Intel i7-3770 CPU,32GB …

java performance java-7 java-8 jmh

76
推荐指数
2
解决办法
9972
查看次数

为什么返回Java对象引用比返回原语要慢得多

我们正在开发一个对延迟敏感的应用程序,并已对所有类型的方法进行微基准测试(使用jmh).在对查找方法进行微基准测试并对结果感到满意之后,我实现了最终版本,但却发现最终版本比我刚刚基准测试的版本3倍.

罪魁祸首是实现的方法返回一个enum对象而不是一个int.以下是基准代码的简化版本:

@OutputTimeUnit(TimeUnit.MICROSECONDS)
@State(Scope.Thread)
public class ReturnEnumObjectVersusPrimitiveBenchmark {

    enum Category {
        CATEGORY1,
        CATEGORY2,
    }

    @Param( {"3", "2", "1" })
    String value;

    int param;

    @Setup
    public void setUp() {
        param = Integer.parseInt(value);
    }

    @Benchmark
    public int benchmarkReturnOrdinal() {
        if (param < 2) {
            return Category.CATEGORY1.ordinal();
        }
        return Category.CATEGORY2.ordinal();        
    }


    @Benchmark
    public Category benchmarkReturnReference() {
        if (param < 2) {
            return Category.CATEGORY1;
        }
        return Category.CATEGORY2;      
    }


    public static void main(String[] …
Run Code Online (Sandbox Code Playgroud)

java low-latency jmh

73
推荐指数
2
解决办法
5327
查看次数

带有-gc true的Java 12与Java 8上流API的神秘微基准测试结果

作为我研究在流中使用复杂过滤器或多个过滤器之间区别的一部分,我注意到Java 12的性能比Java 8慢。

这些奇怪的结果有什么解释吗?我在这里想念什么吗?

组态:

  • Java 8

    • OpenJDK运行时环境(内部版本1.8.0_181-8u181-b13-2〜deb9u1-b13)
    • OpenJDK 64位服务器VM(内部版本25.181-b13,混合模式)
  • Java 12

    • OpenJDK运行时环境(内部版本12 + 33)
    • OpenJDK 64位服务器VM(内部版本12 + 33,混合模式,共享)
  • VM选项: -XX:+UseG1GC -server -Xmx1024m -Xms1024m

  • CPU:8核

JMH吞吐量结果

  • 预热:10次迭代,每次1秒
  • 测量:10次迭代,每次1秒
  • 线程:1个线程,将同步迭代
  • 单位:ops / s

比较表

流+复杂过滤器

public void complexFilter(ExecutionPlan plan, Blackhole blackhole) {
        long count = plan.getDoubles()
                .stream()
                .filter(d -> d < Math.PI
                        && d > Math.E
                        && d != 3
                        && d != 2)
                .count();

        blackhole.consume(count);
    }
Run Code Online (Sandbox Code Playgroud)

流+多个过滤器

public void multipleFilters(ExecutionPlan plan, Blackhole blackhole) {
        long count = plan.getDoubles()
                .stream() …
Run Code Online (Sandbox Code Playgroud)

java benchmarking java-stream jmh java-12

55
推荐指数
1
解决办法
1732
查看次数

Java 11 - 针对Java 8的性能回归?

更新:看到每个方法可能会遇到不同的性能问题,我决定将这个问题分成两个:

  1. Java 11中的空方法明显慢于Java 8
  2. 在Java 11中使用堆栈跟踪的速度明显慢于Java 8

最初的讨论可以在下面找到......


当我遇到一些令人惊讶的数据时,我正在比较我的库在Java 8和11下的性能.这是基准代码:

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.infra.Blackhole;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.concurrent.TimeUnit;

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class MyBenchmark
{
    @Benchmark
    public void emptyMethod()
    {
    }

    @Benchmark
    public void throwAndConsumeStacktrace(Blackhole bh)
    {
        try
        {
            throw new IllegalArgumentException("I love benchmarks");
        }
        catch (IllegalArgumentException e)
        {
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            bh.consume(sw.toString());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

运行jmh 1.21,OracleJDK 1.8.0_192返回:

MyBenchmark.emptyMethod                avgt   25      0.363 ±   0.001  ns/op
MyBenchmark.throwAndConsumeStacktrace  avgt …
Run Code Online (Sandbox Code Playgroud)

performance microbenchmark java-8 jmh java-11

54
推荐指数
0
解决办法
3695
查看次数

Java 8流不可预测的性能下降没有明显的原因

我正在使用Java 8流来迭代包含子列表的列表.外部列表大小在100到1000之间(不同的测试运行),内部列表大小始终为5.

有2个基准测试运行显示意外的性能偏差.

package benchmark;

import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;

import java.io.IOException;
import java.util.concurrent.ThreadLocalRandom;
import java.util.*;
import java.util.function.*;
import java.util.stream.*;

@Threads(32)
@Warmup(iterations = 25)
@Measurement(iterations = 5)
@State(Scope.Benchmark)
@Fork(1)
@BenchmarkMode(Mode.Throughput)
public class StreamBenchmark {
    @Param({"700", "600", "500", "400", "300", "200", "100"})
    int outerListSizeParam;
    final static int INNER_LIST_SIZE = 5;
    List<List<Integer>> list;

    Random rand() {
        return ThreadLocalRandom.current();
    }

    final BinaryOperator<Integer> reducer = (val1, val2) -> val1 + val2;

    final Supplier<List<Integer>> supplier = () -> IntStream
            .range(0, INNER_LIST_SIZE)
            .mapToObj(ptr -> rand().nextInt(100))
            .collect(Collectors.toList());

    @Setup …
Run Code Online (Sandbox Code Playgroud)

java performance lambda java-stream jmh

48
推荐指数
1
解决办法
3498
查看次数

为什么StringBuilder链接模式sb.append(x).append(y)比常规sb.append(x)更快; sb.append(Y)?

我有一个微基准测试,显示非常奇怪的结果:

@BenchmarkMode(Mode.Throughput)
@Fork(1)
@State(Scope.Thread)
@Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS, batchSize = 1000)
@Measurement(iterations = 40, time = 1, timeUnit = TimeUnit.SECONDS, batchSize = 1000)
public class Chaining {

    private String a1 = "111111111111111111111111";
    private String a2 = "222222222222222222222222";
    private String a3 = "333333333333333333333333";

    @Benchmark
    public String typicalChaining() {
        return new StringBuilder().append(a1).append(a2).append(a3).toString();
    }

    @Benchmark
    public String noChaining() {
        StringBuilder sb = new StringBuilder();
        sb.append(a1);
        sb.append(a2);
        sb.append(a3);
        return sb.toString();
    }
}
Run Code Online (Sandbox Code Playgroud)

我期待两个测试的结果相同或至少非常接近.但是,差异几乎是5倍:

# Run complete. Total time: 00:01:41 …
Run Code Online (Sandbox Code Playgroud)

java performance microbenchmark jmh

44
推荐指数
1
解决办法
1850
查看次数

Arrays.stream().map().sum()的不稳定性能

我偶然发现了一个非常不稳定的性能曲线实例,它对原始数组进行了非常简单的map/reduce操作.这是我的jmh基准代码:

@OutputTimeUnit(TimeUnit.NANOSECONDS)
@BenchmarkMode(Mode.AverageTime)
@OperationsPerInvocation(Measure.ARRAY_SIZE)
@Warmup(iterations = 300, time = 200, timeUnit=MILLISECONDS)
@Measurement(iterations = 1, time = 1000, timeUnit=MILLISECONDS)
@State(Scope.Thread)
@Threads(1)
@Fork(1)
public class Measure
{
  static final int ARRAY_SIZE = 1<<20;
  final int[] ds = new int[ARRAY_SIZE];

  private IntUnaryOperator mapper;

  @Setup public void setup() {
    setAll(ds, i->(int)(Math.random()*(1<<7)));
    final int multiplier = (int)(Math.random()*10);
    mapper = d -> multiplier*d;
  }

  @Benchmark public double multiply() {
    return Arrays.stream(ds).map(mapper).sum();
  }
}
Run Code Online (Sandbox Code Playgroud)

以下是典型输出的片段:

# VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/bin/java
# VM options: <none>
# Warmup: 300 iterations, …
Run Code Online (Sandbox Code Playgroud)

java java-8 jmh

42
推荐指数
1
解决办法
1859
查看次数

newInstance vs jdk-9/jdk-8和jmh中的new

我在这里看到很多线程比较并尝试回答哪个更快:newInstance或者new operator.

看看源代码,它看起来newInstance应该慢得多,我的意思是它做了很多安全检查并使用反射.而且我决定先测量一下jdk-8.这是使用的代码jmh.

@BenchmarkMode(value = { Mode.AverageTime, Mode.SingleShotTime })
@Warmup(iterations = 5, time = 2, timeUnit = TimeUnit.SECONDS)   
@Measurement(iterations = 5, time = 2, timeUnit = TimeUnit.SECONDS)    
@State(Scope.Benchmark) 
public class TestNewObject {
    public static void main(String[] args) throws RunnerException {

        Options opt = new OptionsBuilder().include(TestNewObject.class.getSimpleName()).build();
        new Runner(opt).run();
    }

    @Fork(1)
    @Benchmark
    public Something newOperator() {
       return new Something();
    }

    @SuppressWarnings("deprecation")
    @Fork(1)
    @Benchmark
    public Something newInstance() throws InstantiationException, IllegalAccessException {
         return Something.class.newInstance(); …
Run Code Online (Sandbox Code Playgroud)

java performance java-8 jmh java-9

39
推荐指数
1
解决办法
3838
查看次数

为什么在 Scala 中压缩比 zip 快?

我编写了一些 Scala 代码来对集合执行元素操作。在这里,我定义了两个执行相同任务的方法。一种方法使用zip,另一种使用zipped.

def ES (arr :Array[Double], arr1 :Array[Double]) :Array[Double] = arr.zip(arr1).map(x => x._1 + x._2)

def ES1(arr :Array[Double], arr1 :Array[Double]) :Array[Double] = (arr,arr1).zipped.map((x,y) => x + y)
Run Code Online (Sandbox Code Playgroud)

为了在速度方面比较这两种方法,我编写了以下代码:

def fun (arr : Array[Double] , arr1 : Array[Double] , f :(Array[Double],Array[Double]) => Array[Double] , itr : Int) ={
  val t0 = System.nanoTime()
  for (i <- 1 to itr) {
       f(arr,arr1)
       }
  val t1 = System.nanoTime()
  println("Total Time Consumed:" + ((t1 - t0).toDouble / 1000000000).toDouble + "Seconds") …
Run Code Online (Sandbox Code Playgroud)

performance scala scala-collections jmh elementwise-operations

39
推荐指数
4
解决办法
4876
查看次数

如何从JUnit测试中运行JMH?

如何使用JUnit测试在现有项目中运行JMH基准测试?官方文档建议使用Maven shade插件创建一个单独的项目,并在main方法中启动JMH .这是必要的,为什么推荐?

java junit jmh

35
推荐指数
2
解决办法
9754
查看次数