Skip to content
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

Closed
agavrilov76 opened this issue Oct 27, 2019 · 5 comments
Closed

Significant performance degradation since version 3.5.1 #1619

agavrilov76 opened this issue Oct 27, 2019 · 5 comments
Labels

Comments

@agavrilov76
Copy link

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%

@stevenschlansker
Copy link
Member

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

I started working on improving the situation: #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.

@agavrilov76
Copy link
Author

agavrilov76 commented Oct 28, 2019

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.

@stevenschlansker
Copy link
Member

@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 :)

@agavrilov76
Copy link
Author

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.

@stevenschlansker
Copy link
Member

Awesome, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants