有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JMH列表#添加比ArrayList快#新?

我有一个非常简单的JMH基准测试,我读过左右两方面的内容,使用集合的构造函数应该比使用addAll方法更快

然而,我的基准往往恰恰相反

有什么解释吗

@State(Scope.Benchmark)
public static class Strings {
    public String string = "String";
    public List<String> strings = Arrays.asList("String123", "String456", "String789");
}

@Benchmark
@Fork(value = 5, warmups = 3)
public List<String> withStreams(Strings input) {
    return Stream.concat(Stream.of(input.string), input.strings.stream())
            .collect(Collectors.toList());
}

@Benchmark
@Fork(value = 5, warmups = 3)
public List<String> withoutStreamsButWithConstructor(Strings input) {
    List<String> result = new ArrayList<>(input.strings);
    result.add(input.string);
    return result;
}

@Benchmark
@Fork(value = 5, warmups = 3)
public List<String> withoutStreams(Strings input) {
    List<String> result = new ArrayList<>();
    result.add(input.string);
    result.addAll(input.strings);
    return result;
}

PS:关于Streams的例子只是一个实验(实际上是我想确定的实际情况)

结果

# Run complete. Total time: 00:16:31

Benchmark                              Mode  Cnt         Score        Error  Units
App.withStreams                       thrpt  100  12649053,043 ± 222716,712  ops/s
App.withoutStreams                    thrpt  100  50572729,531 ± 324271,706  ops/s
App.withoutStreamsButWithConstructor  thrpt  100  30179733,201 ± 380273,095  ops/s

更新

为该系列添加了以下基准

@Benchmark
@Fork(value = 5, warmups = 3)
public List<String> withoutStreamsWithAddAfter(Strings input) {
    List<String> result = new ArrayList<>();
    result.addAll(input.strings);
    result.add(input.string);
    return result;
}

现在我明白了

# Run complete. Total time: 00:22:00

Benchmark                              Mode  Cnt         Score        Error  Units
App.withStreams                       thrpt  100  13560464,180 ± 201012,539  ops/s
App.withoutStreams                    thrpt  100  47490197,224 ± 864545,886  ops/s
App.withoutStreamsButWithConstructor  thrpt  100  29412182,733 ± 346228,939  ops/s
App.withoutStreamsWithAddAfter        thrpt  100  31030909,677 ±  81494,995  ops/s

所以withoutStreams是最有效的


更新#2

我尝试了以下List<String>

@State(Scope.Benchmark)
public static class Strings {
    public String string = "String";
    public List<String> strings = Arrays.asList("String123", "String456", "String789", "StringAbc", "StringDef", "StringGhi", "StringJkl", "StringMno", "StringPqr", "StringStu");
}

现在,对于构造器@Benchmark来说,结果确实更好了

# Run complete. Total time: 00:22:01

Benchmark                              Mode  Cnt         Score        Error  Units
App.withStreams                       thrpt  100   7291967,397 ± 330614,125  ops/s
App.withoutStreams                    thrpt  100  23575768,665 ± 127039,282  ops/s
App.withoutStreamsButWithConstructor  thrpt  100  27046342,511 ± 182227,005  ops/s
App.withoutStreamsWithAddAfter        thrpt  100  17873682,945 ± 170786,259  ops/s

共 (0) 个答案