In my examples theoretically performance of 2 methods should be pretty similar. In the first case I use array, at the second - ArrayList with ensured capacity.
The results is the following:
LessonBenchmark2.capacityTestArray avgt 5 1,354 ± 0,057 ms/op
LessonBenchmark2.capacityTestArrayListEnsured avgt 5 32,018 ± 81,911 ms/op
Here it seems that array is much faster (1.354 vs 32.018 ms/op). It might be that the settings of my benchmark with JMH is not correct. How to make it right?
Also if I use @Setup(Level.Invocation), then the results are close (1,405 vs 1,496 ms/op):
LessonBenchmark.capacityTestArray avgt 5 1,405 ± 0,143 ms/op
LessonBenchmark.capacityTestArrayListEnsured avgt 5 1,496 ± 0,104 ms/op
However it is said to use Invocation with care. Also Iteration mode seems logically right.
Here is the code:
public static void main(String[] args) throws Exception {
org.openjdk.jmh.Main.main(args);
}
static final int iter = 5;
static final int fork = 1;
static final int warmIter = 5;
@State(Scope.Benchmark)
public static class Params {
public int length = 100_000;
public Person[] people;
public ArrayList<Person> peopleArrayListEnsure;
// before each iteration of the benchmark
@Setup(Level.Iteration)
public void setup() {
people = new Person[length];
peopleArrayListEnsure = new ArrayList<>(length);
}
}
@Benchmark
@Warmup(iterations = warmIter)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Fork(value = fork)
@Measurement(iterations = iter)
public void capacityTestArray(Params p) {
for (int i = 0; i < p.length; i++) {
p.people[i] = new Person(i, new Address(i, i), new Pet(i, i));
}
}
@Benchmark
@Warmup(iterations = warmIter)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Fork(value = fork)
@Measurement(iterations = iter)
public void capacityTestArrayListEnsured(Params p) {
for (int i = 0; i < p.length; i++) {
p.peopleArrayListEnsure.add(new Person(i, new Address(i, i), new Pet(i, i)));
}
}
public static class Person {
private int id;
private Address address;
private Pet pet;
public Person(int id, Address address, Pet pet) {
this.id = id;
this.address = address;
this.pet = pet;
}
}
public static class Address {
private int countryId;
private int cityId;
public Address(int countryId, int cityId) {
this.countryId = countryId;
this.cityId = cityId;
}
}
public static class Pet {
private int age;
private int typeId;
public Pet(int age, int typeId) {
this.age = age;
this.typeId = typeId;
}
}