Я заметил значительное снижение производительности при переходе с версии 3.5.1 на версию 3.10.1 (Dropwizard 1.3.5 -> 2.0.X) при использовании преобразователей строк и аргументов Java Beans для типов Java, имеющих более 20 полей.
Я создал программу микротестов :
Привет, @ Alexey1Gavrilov , спасибо, что сообщили об этом! Я согласен, что определенно были некоторые регрессы.
Я начал работать над улучшением ситуации: https://github.com/jdbi/jdbi/pull/1607
В настоящее время он просто ждет обзора и некоторых тестов, чтобы убедиться, что мы не сломаем все :)
У вас есть время, чтобы самостоятельно убедиться, что исправления, указанные выше, помогают вашему варианту использования?
Спасибо и надеемся, что скоро мы внесем исправление.
Очень хорошие новости, что вы уже работаете над улучшением! Я могу подтвердить, что # 1607 значительно улучшает производительность. Моя программа микротестов работает примерно на 10-15% быстрее с этим PR, чем с 3.5.1. Отличная работа!
Мы также реализовали настраиваемый слой кеша для сопоставления имен столбцов, который еще больше повысил производительность. Идея заключалась в том, чтобы кэшировать сравнение columnName
и javaName
для всех полей, обрабатываемых экземпляром Jdbi
. Вот фрагмент кода:
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;
}
<strong i="10">@Override</strong>
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);
}
<strong i="11">@Override</strong>
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<>();
}
<strong i="12">@Override</strong>
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()));
...
Пожалуйста, дайте мне знать, имеет ли смысл сравнение имен столбцов кеширования (это связано с некоторыми затратами на сборку мусора), если я могу открыть PR.
@ Alexey1Gavrilov , я только что выпустил 3.11.0 с включенным # 1607.
Я счастлив улучшить производительность сопоставления имен столбцов, хотя кеширование всех сопоставлений, возможно, является тяжелым решением. У вас есть проблемы с определенным сопоставителем - возможно, с сопоставителем SnakeCase? Давайте начнем с лучшего описания проблемы, которая влияет на вас, и разработаем решение, которое, возможно, кеширует :)
Протестировано 3.11.1 - улучшение на 20% по сравнению с 3.5.1! Отличная работа!
Я создам отдельную проблему для сопоставителя SnakeCase, и мы обсудим там возможные решения.
Отлично, спасибо!
Самый полезный комментарий
Протестировано 3.11.1 - улучшение на 20% по сравнению с 3.5.1! Отличная работа!
Я создам отдельную проблему для сопоставителя SnakeCase, и мы обсудим там возможные решения.