Jdbi: Significant performance degradation since version 3.5.1

Created on 27 Oct 2019  ·  5Comments  ·  Source: jdbi/jdbi

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%

bug

Most helpful comment

Tested 3.11.1 - 20% improvement comparing to 3.5.1! Great work!
I'll create a separate issue on the the SnakeCase matcher and we discuss possible solutions there.

All 5 comments

Hi @Alexey1Gavrilov , thanks for reporting this! I agree there's definitely been some regressions.

I started working on improving the situation: https://github.com/jdbi/jdbi/pull/1607
Currently, it is just waiting on review and some testing to make sure we do not break everything :)

Do you have some time to independently verify that the fixes linked above help your use case?
Thanks and hopefully we'll have a fix merged in soon.

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 columnName and javaName for all the fields processed by Jdbi instance. Here is a code snippet:

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!
I'll create a separate issue on the the SnakeCase matcher and we discuss possible solutions there.

Awesome, thank you!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

keith-miller picture keith-miller  ·  3Comments

johanneszink picture johanneszink  ·  4Comments

kkrgwbj picture kkrgwbj  ·  4Comments

jimmyhmiller picture jimmyhmiller  ·  6Comments

Romqa picture Romqa  ·  5Comments