Jdbi: バージョン3.5.1以降のパフォーマンスの大幅な低下

作成日 2019年10月27日  ·  5コメント  ·  ソース: jdbi/jdbi

20以上のフィールドを持つJavaタイプにJavaBeans行および引数マッパーを使用しているときに、バージョン3.5.1からバージョン3.10.1(Dropwizard 1.3.5-> 2.0.X)に移行すると、パフォーマンスが大幅に低下することに気付きました。

問題を再現するために、マイクロベンチマークプログラムhttps://github.com/Alexey1Gavrilov/jdbi-testを作成しました。 3.5.1と3.10.1の実行時間は、最大70%異なる可能性があります

bug

最も参考になるコメント

テスト済み3.11.1-3.5.1と比較して20%の改善! すごい仕事!
SnakeCaseマッチャーで別の問題を作成し、そこで可能な解決策について説明します。

全てのコメント5件

こんにちは@ Alexey1Gavrilov 、これを報告してくれてありがとう! 私は確かにいくつかの後退があったことに同意します。

私は状況の改善に取り組み始めました:https://github.com/jdbi/jdbi/pull/1607
現在、すべてを壊さないことを確認するためのレビューといくつかのテストを待っています:)

上記のリンクされた修正がユースケースに役立つことを独自に検証する時間はありますか?
おかげで、うまくいけば、すぐに修正がマージされます。

あなたがすでに改善に取り組んでいるという非常に良いニュースです! #1607がパフォーマンスを大幅に向上させていることを確認できます。 私のマイクロベンチマークプログラムは、そのPRで約10〜15%速く実行され、その後3.5.1で実行されます。 すごい仕事!

また、パフォーマンスをさらに向上させる列名マッチャーのカスタムキャッシュレイヤーを実装しました。 基本的には、 Jdbiインスタンスによって処理されるすべてのフィールドのcolumnNamejavaNameの比較をキャッシュするという考え方でした。 コードスニペットは次のとおりです。

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 、#1607を含めて3.11.0をリリースしました。

列名のマッチングのパフォーマンスを改善できてうれしいですが、すべてのマッチングをキャッシュすることはおそらく重い解決策です。 特定のマッチャー(おそらくSnakeCaseマッチャー)に問題がありますか? あなたに影響を与えている問題のより良い説明から始めて、おそらくキャッシングであるかもしれない解決策を考案しましょう:)

テスト済み3.11.1-3.5.1と比較して20%の改善! すごい仕事!
SnakeCaseマッチャーで別の問題を作成し、そこで可能な解決策について説明します。

素晴らしいありがとう!

このページは役に立ちましたか?
0 / 5 - 0 評価