続・Kijimunaのパフォーマンス

パフォーマンスチューニングは後回し、と言っておきながら、やはり気になって調査。

で、Kijimunaが重いと感じた原因がなんとなくわかった。直接の原因はvalidate処理が大量に実行されていたこと。

今回リファクタリング対応を行うためにSeasarのexamplesプロジェクトをワークスペースにコピーしたのだが、コピー(追加)した*.javaファイルの数だけvalidate処理が実行されていたみたい。validate処理自体は初回にキャッシュしさえすればそれほど重くないのだが、なんせ*.javaファイル数回実行されてしまうから、重くなっていた。

class DiconValidator
  public build(){
    ...
    IResourceDelta resourceDelta = getDelta(project);
      if (resourceDelta != null) {
         resourceDelta.accept(new DeltaVisitor(getNatureID(), this, monitor));
      }
    ...
    public void handleFileAdded(IFile addedFile,..) {
      fullValidate(addedFile.getProject(), monitor);
    }
    ...
}}
class DeltaVisitor{
  public boolean visit(IResourceDelta delta)
    IFile file = (IResouce)delta.getResource();
    ..
    if (delta.getKind() == IResourceDelta.ADDED) {
      builder.handleFileAdded(file, false, monitor);
    ..
  }

ワークスペースに変更があるとDiconValidator#build()が呼ばれて、変更・追加があったファイル数分DeltaVisitor#visit()が呼び出され、DiconValidator#fullValidate()が呼び出されるという感じ。
fullValidate()は結局project単位で行っているので、resourceDelta内にひとつ以上*.javaファイルがあれば一度だけfullValidateする、でもOKなはず。で、以下のように修正してみた。

class DiconValidator

  public build(){
    booleanneedFullValidate = false; //追加
    ...
    public void handleFileAdded(IFile addedFile,..) {
      //fullValidate(addedFile.getProject(), monitor);
      needFullValidate = true;
    }
    ...
    public void handleFinish(IProject project, IProgressMonitor monitor) {
      //追加
      if(needFullValidate){
        fullValidate(project, monitor);
        needFullValidate = false;
      }
      ...
}}

まあパフォーマンスが低下するのは多くの*.javaをプロジェクトに追加した場合のみなので、それほど劇的な改善というわけではないけど。いやーパフォーマンスチューニングは楽しいな(解決した瞬間だけ)。