场景
Java中使用JMH(Java Microbenchmark Harness 微基准测试框架)进行性能测试和优化:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/131723751
参考以上性能测试工具的使用。
阿里巴巴《java开发手册》泰山版关于集合转数组时规范声明:
【强制】使⽤集合转数组的⽅法,必须使⽤集合的 toArray(T[] array),传⼊的是类型完全⼀致、⻓度为0的空数组。
反例:直接使⽤ toArray ⽆参⽅法存在问题,此⽅法返回值只能是 Object[] 类,若强转其它类型数组将出现ClassCastException 错误
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
实现
新建测试类,分别测试以上四种情况
//测试完成时间
@BenchmarkMode(Mode.AverageTime)
//设置统计结果的时间单位
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 2,time = 1,timeUnit =
TimeUnit.SECONDS)
//测试次数和时间,参数同上
@Measurement(iterations = 5,time = 1,timeUnit =
TimeUnit.SECONDS)
//fork一个线程,进行 fork 的次数,可用于类或者方法上。如果
fork 数是 2 的话,则 JMH 会 fork 出两个进程来进行测试。
@Fork(1)
//通过 State 可以指定一个对象的作用范围,JMH 根据 scope 来进行实例化和共享操作。@State
可以被继承使用,
//Scope.Thread:默认的 State,每个测试线程分配一个实例
@State(Scope.Thread)
public class
ListToArrayTest {
public static void main(String[]
args) throws RunnerException {
//启动基准测试
Options options = new OptionsBuilder()
.include(ListToArrayTest.class.getSimpleName())//要导入的测试类
.build();
new
Runner(options).run();//执行测试
}
//list设置为0
@Benchmark
public void listZeroTest(){
List<String> list = new
ArrayList<>(3);
list.add("badao");
list.add("de");
list.add("chengxvyuan");
String[] array =
list.toArray(new String[0]);
}
//等于size
@Benchmark
public void listEqualTest(){
List<String> list = new
ArrayList<>(3);
list.add("badao");
list.add("de");
list.add("chengxvyuan");
String[] array =
list.toArray(new String[list.size()]);
}
//大于size
@Benchmark
public void listGranterTest(){
List<String> list = new
ArrayList<>(3);
list.add("badao");
list.add("de");
list.add("chengxvyuan");
String[] array =
list.toArray(new String[1000]);
}
//小于size
@Benchmark
public void listLessTest(){
List<String> list = new
ArrayList<>(3);
list.add("badao");
list.add("de");
list.add("chengxvyuan");
String[] array =
list.toArray(new String[2]);
}
}
测试结果
//Benchmark Mode Cnt Score
Error Units
//ListToArrayTest.listEqualTest avgt
5 10.533 ± 1.294 ns/op
//ListToArrayTest.listGranterTest avgt 5 308.779 ±
7.831 ns/op
//ListToArrayTest.listLessTest avgt
5 10.437 ± 0.572 ns/op
//ListToArrayTest.listZeroTest avgt 5 10.277 ±
0.481 ns/op
从上面的结果中可以看出,阿里手册推荐的设置为0的方法性能最好,大于size的方法性能最差。
具体原因已经给出:
1) 等于 0,动态创建与 size 相同的数组,性能最好。
2)
⼤于 0 但小于 size,重新创建⼤小等于 size 的数组,增加 GC 负担。
3) 等于
size,在⾼并发情况下,数组创建完成之后,size 正在变⼤的情况下,负⾯影响与 2 相同。
4) ⼤于
size,空间浪费,且在 size 处插⼊ null 值,存在 NPE 隐患。