2011年7月27日水曜日

coberturaが猛烈に遅い!...けど解決した

■概要

junitの網羅率測定する為に、coberturaを利用する事が多いと思います。

# 当方久しぶりにjavaを触ったので最近のトレンドにはとんと疎くなりました。もっと良いのがあれば教えてください。

しかしこれが猛烈に遅い!軽快に進めたいのですが、ネックになりそうなので調査しました。

■解説

coberturaの実行はantから行っています。通常

1. コンパイル
2. instrument (coberturaを埋め込む)
3. junit実行


の順番で実行する事になりますが、 3. が非常に遅いのです。

3. の実行は
<junit fork="yes" dir="${basedir}">
  <classpath location="${instrumented.dir}" />
  <classpath location="${classes.dir}" />
  <classpath refid="cobertura.classpath" />
  <formatter type="xml" />
  <test name="${testcase}" todir="${reports.xml.dir}" if="testcase" />
  <batchtest todir="${reports.xml.dir}" unless="testcase">
    <fileset dir="${src.dir}">
      <include name="**/*Test.java" />
    </fileset>
  </batchtest>
</junit>

の様な記載を行うと思いますが、上記だと遅くなってしまいます。

何故なら、antがjunitを起動する際にプロセスのforkを行うのですが、forkはTestCase毎に行われるようです。
複数回のforkを通して網羅率の測定を行う必要がある為、「cobertura.ser」というファイルを
かいして測定を行います。

ところがforkする毎にcobertura.serに、シリアライズ・デシリアライズを行うためのその
オーバーヘッドが大きくなります。実際topコマンド確認するとCPUバウンドな処理である事が分かります。


そこでant 1.6.2より導入された、forkmodeを設定します。

<junit fork="yes" forkmode="once" dir="${basedir}">
....

上記の設定により、junitを実行するプロセスは"一度だけ"起動される為、シリアライズ・デシリアライズのオーバーヘッドが無くなり、非常に高速にテストの実行が可能です。

1 件のコメント:

  1. こんばんは。

    何度も実行する無駄をきっちり省けるのは、安心ですね。

    返信削除