New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Significant performance degradation since version 3.5.1 #1619
Comments
Hi @Alexey1Gavrilov , thanks for reporting this! I agree there's definitely been some regressions. I started working on improving the situation: #1607 Do you have some time to independently verify that the fixes linked above help your use case? |
A very good news that you have already been working on the improvement! I can confirm that #1607 does significantly improve the performance. My micro benchmark program runs approximately 10-15% faster with that PR, then on 3.5.1. Great work! We have also implemented a custom cache layer for the column name matcher which improves the performance even further. The idea was basically to cache the comparison of the class CachingColumnNameMatcher implements ColumnNameMatcher {
private static class Column {
final String columnName;
final String javaName;
private Column(String columnName, String javaName) {
this.columnName = columnName;
this.javaName = javaName;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Column column = (Column) o;
return Objects.equals(columnName, column.columnName) &&
Objects.equals(javaName, column.javaName);
}
@Override
public int hashCode() {
return Objects.hash(columnName, javaName);
}
}
private final ColumnNameMatcher delegate;
private final ConcurrentMap<Column, Boolean> cache;
CachingColumnNameMatcher(final ColumnNameMatcher delegate) {
this.delegate = delegate;
this.cache = new ConcurrentHashMap<>();
}
@Override
public boolean columnNameMatches(final String columnName, final String javaName) {
final Column key = new Column(columnName, javaName);
return cache.computeIfAbsent(key, (c) -> delegate.columnNameMatches(columnName, javaName));
}
}
...
final ReflectionMappers reflectionMappers = jdbi.getConfig().get(ReflectionMappers.class);
reflectionMappers.setColumnNameMatchers(
reflectionMappers.getColumnNameMatchers().stream()
.map(CachingColumnNameMatcher::new)
.collect(Collectors.toList()));
... Please let me know if the caching column name comparison makes sense to you (it comes with some garbage collection cost), if I can open a PR. |
@Alexey1Gavrilov, I just released 3.11.0 with #1607 included. I am happy to improve the performance of column name matching, although caching all matching is possibly a heavy-weight solution. Are you having issues with a specific matcher -- the SnakeCase matcher perhaps? Let's start from a better description of the problem that's affecting you and devise a solution, which might possibly be caching :) |
Tested 3.11.1 - 20% improvement comparing to 3.5.1! Great work! |
Awesome, thank you! |
I have noticed significant performance degradation when going from version 3.5.1 to version 3.10.1 (Dropwizard 1.3.5 -> 2.0.X) while using Java Beans row and argument mappers for Java types having 20+ fields.
I've created a micro benchmark program: https://github.com/Alexey1Gavrilov/jdbi-test to reproduce the issue. The execution time on 3.5.1 and 3.10.1 can be different as high as 70%
The text was updated successfully, but these errors were encountered: