I have done some small benchmarks where I iterate over different collections and I found weird difference between HashSet and LinkedHashSet. When I execute exactly the same code but for different types(Integer vs String), I receive different results:
- For Integer iteration LinkedHashSet is faster(6,53[ms] vs 20[ms])
- For String iteration HashSet is faster(55,92[ms] vs 67[ms])
public void iterateHashSet() {
HashSet<String> strings = addStrings();
List<Long> executionsTimes = new ArrayList<>();
IntStream.range(0, ATTEMPT_COUNT).forEach(i -> {
if (i >= ATTEMPT_COUNT * 0.7) {
long start = System.nanoTime();
strings.forEach(s -> {
;
});
long resultTime = (System.nanoTime() - start);
executionsTimes.add(resultTime);
} else {
strings.forEach(s -> {
;
});
}
});
averageExecutionTime(executionsTimes);
}
public void iterateLinkedHashSet() {
LinkedHashSet<String> strings = addStrings();
List<Long> executionsTimes = new ArrayList<>();
IntStream.range(0, ATTEMPT_COUNT).forEach(i -> {
if (i>= ATTEMPT_COUNT * 0.7) {
long start = System.nanoTime();
strings.forEach(s -> {
;
});
long resultTime = (System.nanoTime() - start);
executionsTimes.add(resultTime);
} else {
strings.forEach(s -> {
;
});
}
});
averageExecutionTime(executionsTimes);
}
Size of each set is 1000000. For Integer test structure is the same besides the type of course :) I used ATTEMPT_COUNT to warmup JVM.
Do you have any idea where this difference comes from?
E: This is how I add strings:
private LinkedHashSet<String> addStrings() {
LinkedHashSet<String> strings = new LinkedHashSet<>();
Random random = new Random();
for (var i = 0; strings.size() < ELEMENT_COUNT; i++) {
int number = random.ints(0, strings.size()+1)
.findFirst()
.getAsInt();
StringBuilder stringBuilder = new StringBuilder();
if (i % 2 == 0) {
stringBuilder
.append("Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +
"Etiam quis tortor a ex bibendum pulvinar id vel erat. " +
"Pellentesque tempus sit amet ante in iaculis. Etiam sit amet mattis ligula. " +
"Curabitur aliquet elit dignissim, ullamcorper lorem laoreet, sagittis quam." +
" Maecenas fringilla egestas enim eu dignissim. Ut fermentum ligula eu tortor eleifend, " +
"et eleifend arcu tristique. Sed sit amet arcu diam. Pellentesque non suscipit massa. " +
"Suspendisse a mi ante. Curabitur laoreet non turpis sed fringilla. Aliquam dolor velit," +
" luctus nec bibendum in, dignissim eget est. Etiam convallis mattis lectus vitae euismod.")
.append(number);
} else {
stringBuilder
.append("Vivamus iaculis vulputate lectus sed cursus. Suspendisse efficitur " +
"molestie efficitur. Suspendisse et tortor a mi sagittis tempor porta vel eros. Curabitur nec " +
"pellentesque magna, in gravida risus. Etiam mollis, quam a sollicitudin fringilla, tellus massa " +
"lobortis neque, eget mattis nunc nisl eget erat. Cras finibus felis a nisl porta, at pellentesque" +
" nisi elementum. Sed ac dui lectus. Praesent id gravida metus, et tristique felis. Sed at massa" +
" ipsum. Duis at sapien quam. Aliquam erat volutpat. Cras gravida fermentum feugiat. Vivamus nec" +
" consequat diam. Proin ut purus laoreet massa tempus molestie. Maecenas luctus porta sapien id" +
" tincidunt. Maecenas posuere feugiat commodo.")
.append(number);
}
strings.add(stringBuilder.toString());
}
return strings;
}
Integers:
private LinkedHashSet<Integer> addNumbers() {
LinkedHashSet<Integer> numbers = new LinkedHashSet<>();
Random random = new Random();
for (var i = 0; numbers.size() < ELEMENT_COUNT; i++) {
int number = random.ints(0, Integer.MAX_VALUE)
.findFirst()
.getAsInt();
numbers.add(number);
}
return numbers;
}