assertj: 3.9.1 has bad performance regression
Summary
After upgrading to 3.9.1, I notice a regression in term of performance. By digging down, I notice that it spends a lot of time in the following code
public static TypeComparators defaultTypeComparators() {
TypeComparators comparatorByType = new TypeComparators();
comparatorByType.put(Double.class, new DoubleComparator(DOUBLE_COMPARATOR_PRECISION));
comparatorByType.put(Float.class, new FloatComparator(FLOAT_COMPARATOR_PRECISION));
return comparatorByType;
}
It sounds like it performs too much memory allocation and reflection cost on the following stack trace.
java.lang.Class.getEnclosingMethod0() Class.java (native)
java.lang.Class.getEnclosingMethodInfo() Class.java:1072
java.lang.Class.getEnclosingClass() Class.java:1272
java.lang.Class.getSimpleBinaryName() Class.java:1443
java.lang.Class.getSimpleName() Class.java:1309
org.assertj.core.internal.TypeComparators$$Lambda$77.apply(Object)
java.util.Comparator.lambda$comparing$77a9974f$1(Function, Object, Object) Comparator.java:469
java.util.Comparator$$Lambda$78.compare(Object, Object)
java.util.TreeMap.compare(Object, Object) TreeMap.java:1295
java.util.TreeMap.put(Object, Object) TreeMap.java:538
org.assertj.core.internal.TypeComparators.put(Class, Comparator) TypeComparators.java:99
org.assertj.core.internal.TypeComparators.defaultTypeComparators() TypeComparators.java:48
org.assertj.core.api.AbstractIterableAssert.<init>(Iterable, Class) AbstractIterableAssert.java:112
org.assertj.core.api.FactoryBasedNavigableIterableAssert.<init>(Iterable, Class, AssertFactory) FactoryBasedNavigableIterableAssert.java:32
org.assertj.core.api.IterableAssert.<init>(Iterable) IterableAssert.java:49
org.assertj.core.api.Assertions.assertThat(Iterable) Assertions.java:2586
This additional overhead is caused by the change from HashMap to TreeMap and the use of Comparator.comparing(Class::getSimpleName)
assertj 3.8.0 does not have this problem.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 63 (57 by maintainers)
I understand. We have 2k unit tests, all using
JUnitSoftAssertions
rule. I’m not sure I can isolate/reproduce the issue in a single test file, let see what I can do.I have done some more profiling for the assertj use case, could you try Byte Buddy 1.8.10?
So if I understand correctly it is safe to make
new ByteBuddy()
a field inSoftProxies
instead of creating one everytime in:I’ll add
.with(TypeValidation.DISABLED)
thanks for the tip.Let me take a stab at it
I use a lot of Assertions.assertThat in a tight loop. It pretty much consumes almost 100% of the cpu within the loop. I would suggest that you don’t even get TypeComparators.defaultTypeComparators() at all. You should have a constant copy of that map and use it if the assert does not override that.