ソフトウェアメトリクス2:ソースコードの規模

いまさら Lines-of-code? 

 ソースコードの規模を測定する際に、最もよく使われるメトリクスはコード行数、いわゆるLines-of-code (LOC) でしょう。古くからあるメトリクスである上に、計測も簡単にできます。Linux 環境であれば、wc -l コマンド一発ですし、エディタで常時表示させることもできます。

 ただし、ご存知とおりLOC は取り扱いが難しいメトリクスでもあります。特に、LOC を作業量の見積もりや、開発チームのパフォーマンスの計測に使う場合は、使い方を誤ると批判が生まれます。例えば、2つの異なるチームが「オンラインでの支払いシステム」を開発した時に、同じ期間で1000行のコードで開発したのと、100行のコードで開発したのでは、どちらのチームがパフォーマンスがよいと言えるでしょうか。ほぼ同じ機能であるならば、開発時のコストはもちろん、その後の保守メンテナンスのことも考えれば、より少ない行数で実現できた方がよいことは疑いようがありません。最近のNo Code の流行にもあるように、全くコードを書かずに実現できれば、それが最も効率が良いとも言えます。

 LOC の問題点の一つは、単純な変数の代入も、複雑な算術演算ステートメントも、同じ1行でカウントされてしまうことにあります。この問題点を解決する一つのアイディアは、行の複雑度に応じて重み付けをすることですが、「17行目のステートメントが45行目のステートメントよりも2倍の重みを持っている」などと定量的に表現することは容易ではありません。LOC は、その名の通り単位「コードの行数」を数えただけのものであり、開発時間や、生産性や、コストに直接変換できるものではありません。

 このように、様々な問題をもつメトリクスではありますが、それでもなおLOC が有用な場面は多数あります。例えば、LOCの絶対量ではなく相対的な変化に注目してチームの開発フェーズの変化を知ることができます。前述の通り、LOCの値そのものはチームの生産性と必ずしも関連性があるとは言えませんが、同じプロジェクト、同じチームにおいて、チームの先週のLOCと今週のLOC を比較することで、増加傾向であれば「設計フェーズから実装フェーズに入った」とか、減少傾向であれば「実装が一段落してテストフェーズに入った」などと類推することができます。

 他には、LOC はテストや保守の基準値として使われることもあります。10万行のソフトウェアは、1万行のソフトウェアよりも保守やテストのコストがかかるのは同意できるところだと思います。バグの数をLOC で割ったものを「バグ密度」と定義し、ソフトウェア品質の基準値として使っているチームもあります。

 LOCの計測方法にはいくつかの定義があり、チームや組織で採用する場合は同じ定義を一貫して使うことが重要です。単純にテキストファイルとしての行数(Physical LOC)を使うこともありますが、多くの場合、空行とコメント行を除いた行数(Non-comment LOC: NLOC)や、NLOCからさらに、「2つの命令が書かれた行は2行と数える」、「括弧だけの行を除く」などの換算をした行数(Logical LOC: LLOC)を用いることが多いでしょう。コメントの行数をComment lines of program text: CLOC として計算し、ソースコード中のコメント密度を CLOC/LOC として定義し、一定以上を保つようなルールを設けているチームもあります。 

Halstead Volume

 ソースコードの規模を求めるメトリクスとしては、LOC (とその派生)が使われることがほとんどですが、Halstead Volume というメトリクスも一部で使われているので紹介します。例えば、Halstead Volume は、MS Visual Studio において、保守容易性を測定するための指標の入力値の一つとして使用されています

 Maurice Howard Halstead は、1977年に出版した論文においてソフトウェアの複雑度の測定方法を提唱しました。その複雑度の計算に必要な値の一つが、ソフトウェアの規模の指標でHalstead Volume と呼ばれています。定義は以下の通りです。

 あるプログラムを、演算子またはオペランドとして分類されたトークンの集合として定義し、以下の値を計算します。

  • η1 = 固有の演算子の数
  • η2 = 固有のオペランドの数
  • N1 = 演算子の総出現回数
  • N2 = オペランドの総出現回数

ここで、プログラムのVocabulary (語彙) を η = η1 + η2 とします。プログラムのLength (長さ) を N = N1 + N2 とします。ηとN を使って、Halstead Volume は以下のように定義されます。

 Halstead は、他にもブログラムの複雑度(Difficultiy)や、作業量(Effort)、開発にかかる時間(Time required to program) などを定義していますが、Volume 以外のメトリクスに関しては経験的な(empirical)モデルと数学モデルとの関係が不明確であるとの批判も多いようです。

注意点

以下では、ソースコードの規模を測定する際に考慮すベきいくつかの注意点を挙げておきます。

プログラミング言語間の違い

同じようなソフトウェアを開発する際に、選択するプログラミング言語によってコードの規模が変わります。極端な話、LISP で書いた場合は、同じ動作でもJava とは異なる行数になるでしょう。異なるプログラミング言語が混在したプロジェクトにおいて、LOC からバグの数や工数の概算をするつもりであれば、プログラミング言語に応じてなんらかのファクターをかける必要があるかもしれません。

再利用コードの取り扱い

プロジェクトにおいて、車輪の再発明を防ぐために、過去のコードを利用したり、オープンソースのライブラリを組み合わせるのは一般的です。また、開発環境や導入しているフレームワークが自動的に生成するコードもあるでしょう。開発工数の見積もりなどで、コードの規模を測定する際は、そのような再利用コードを除外する必要があります。

再利用されたコードを数えることは、思ったより単純ではありません。例えば、NASA/Goddard’s Software Engineering Laboratoryでは、再利用のレベルを次のように定義しています(1995)。

  1. 逐語的に再利用されている。ユニット内のコードがそのまま再利用されている。 
  2. わずかに変更されている。25%以下のLOCが変更されていた。 
  3. 大幅に変更されている。25%以上のLOCが変更された。 
  4. 新規である。以前に建設されたユニットに由来するコードはない。 

完全なコピーではなく上記の2, 3 のように一部改変された再利用コードをプロジェクト全体から検出するにはツールが必要になります。Sider Labs の使用を検討して下さい。

上記のように、コードの規模を測定するには、使われているプログラミング言語や再利用の度合い、その他の要因への依存性を考慮しなければなりません。しかしながら、最も簡単に測定できる便利なメトリクスでもあります。賢く利用していきましょう。

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.