メトリックの概要

関数に関するメトリック

略 号 説 明 
STFIL ソースファイルの名前 
STNAM メトリック測定を行う関数の名前 
STCYC サイクロマティック複雑度(経路複雑度)
基本的には判定数に1を加えたものです。アルコリズム全体の複雑度を測定します。経路複雑度が高い場合、モジュール化が不十分であり、一つの関数に含まれるロジックが多すぎるということを示しています。
ある組織では、プログラミング基準としてひとつの関数の最大経路複雑度は10未満という規格を定めています。
 
経路複雑度は、QACによるデモグラフィック解析で用いる5つのメトリックのうちのひとつであり、これがある値を越えると警告を発します。デフォールトの基準値はやや複雑(10)、複雑(30)、かなり複雑(100)の3ランクです。
 
McCabe(1976)はメトリックの導入と同時に経路複雑度について基本的な議論を展開しました。
STMCC “マイヤーズ インターバル(Myer's Interval)”と呼ばれ、経路複雑度の拡張指標です。対の値で上限と下限を表します。下限値は純粋な経路複雑度で、上限値は下限値プラス合成条件( && あるいは || )の数です。
 
マイヤーズインターバルが大きい時は合成条件判定が多く、理解し難いコード傾向にあることを示しています。下限値と上限値の差であるマイヤーズインターバルが10以上の場合は、通常よりも難易度が高いとみなされます。
STMIF 制御構造の最大ネスティング数です。STMIFはデモグラフィック解析で使用する5つの指標のうちのひとつです。
 
QACがこの指標値に基づく警告を出さないまでも、デモグラフィック解析結果を改善するためにもっとこの値を下げたいと考えることも有るでしょう。ネスティング部分のコードを別々の関数に分けることによってこれを達成でき、ネスティングと関数あたりの平均経路複雑度を減らせばコードの読み易さも改善します。
 
PRLでは“ブラックボックス”テストのステートメントカバレッジと、この指標STMIFとの間に強い相関が有ることを見いだしました。
 
制御構造が深くネスティングしている場合は、通常の“ブラックボックス“テスト方式でテストするのが本質的に困難です。STMIF値の高い関数では、ネスティング条件を確実に検証するために注意深い(吟味された)”ホワイトボックス”テストが必要です。
 
注1:    “ブラックボックス”テスト
テストコードの論理と構造を考慮せずにテストデータを生成するもの。
一般に、生成されるテストデータは実際のサンプルデータであったり、システムユーザあるいは潜在的ユーザが与えています。
 
注2:    “ホワイトボックス”テスト
テストデータの生成を制御するためにテストコードの論理と構造を利用するもの。こうしたテストデータは、コードが識別する境界条件に基づいて作成します。
高いカバレッジを達成する為には大変効果的なものの、テストケースの作成には努力が必要でコストが高くなります。
QACのようなツールは、テストを行う上での潜在的な問題点を識別できる為、テストデータの作成にも大変有効です。
 
STSUB 関数呼び出しの数を示します。他の関数を多く呼び出している関数は、機能が複数なコンポーネントに分散しているために、理解し難いものになります。
 
構造化設計が十分でない証拠で、コーリングツリーが急速に分散する傾向にあります。
 
Brandl(1990)の文献を参照して下さい。複雑度とコーリングツリーの形状を明らかにした優れた文献です。
STAKI アキヤマ(秋山)指標。これは経路複雑度と関数呼び出し数の和です。独立した指標ではありませんが、歴史的にCASEの文献で触れられているために組み込まれています。
 
詳細は秋山(1971)およびShooman(1983)の文献を参照下さい。
STLIN メンテナンス可能なコード行数。長い関数は1画面あるいは1ページに収まらないという理由だけでも、読みにくいということは一般に認められていることです。
 
PlumHallガイドラインで、Thomas Plumは関数の行数は50を越えないよう推奨しています。
 
Plumはさらに続けて、ひとつのモジュールのなかの関数や平均コード行数がこの値(50)を超えている場合は、設計が不適切であるとしています。
STXLN 実行コード行数。基本的にはSTLINから宣言文の行数を引いたものです。
STBAK 後方へのジャンプ数。幸運にもCではgotoの使用は非常に希であり、統計では常にゼロでしょう。
 
もしそうでないとするとコードに正真正銘の問題があるか、あるいは開発者の責任であると言えます。STBAKは主にQAFortran(PRL社の製品)との互換性のために採用されています。
STELF 中途半端なelse-if文の数。if-else-if構造文のうち関連するelse文を持っていないものの数を示します。QACはこうした事例ごとに警告を発します。
 
従って、つまらない、しかもエラーになりやすい使い方がモニタできる手短な参照統計値であるといえます。
STGTO 関数の中のgoto文の数。恐れられているgoto文の使用に関しては時として論議のあるところです。(例えばエラー処理を手軽に行うために使用するような場合。)しかし手書きのコードでは滅多にお目にかかりません。
 
Plum Hallガイドラインでは単にgoto文は使用すべきでないと指摘されており、その他の権威者もこの点では同意しています。(Dijsktraは論文“Goto considered harmfull”でこの点に関して述べています。)PRLの経験でも一般にC言語ではgoto文はほとんど使用されていません。
STKNT ノットカウント数。ノットとは制御フローの交差を言い、構造化されていないコードであることを示しています。Cにおいてノットが発生するのはループのなかのcontinue、break、そして大抵はgoto文が原因です。
STKDN ノット密度。実行行あたりのノット数です。単純にSTKNT/STXLNから求めます。(STKNTがゼロの場合はSTKDNはゼロと定義します。)
STUNV 未使用及び再使用されていない変数の数。
再使用されていない変数とは、セットされたもののそれ以降使われていない変数を言います。
 
これらの変数は一般にコードの中に散在しており、プログラマが変更を繰り返すことによる“ソフトウェアエージング(ソフトウェアがより多くの年代を重ねること)”で発生する事が多いようです。
STLCT 宣言されたローカル変数の数。
STPTH スタティックパスカウント(概算値)。NejmehのNPATH(1988)統計と類似しており、関数の中の可能性のあるパス(経路)数の上限値です。パスカウント値の高い関数は多くの異なったテストデータセットを必要とするため、テストが非常に困難です。実際のパスカウントは次の不等式に従います。
 
(経路複雑度) ≦ (実際のパスカウント) ≦ (スタティックパスカウント)
 
スタティックパスカウントはQACのデモグラフィック解析で採用されているメトリックのひとつです。ある値を越えると警告を発します。デフォールト値は200、1000、10000です。
Nejmeh(1988)とHattonおよびHopkins(1989)の個別の研究で、パスカウントが200~300を越えるとメンテナンス上問題が発生することが指摘されています。同様の研究が他の組織でも行われており、AT&Tではパスカウント約200で保守費用曲線の変化点となるとの認識を持っています。
 
経路複雑度がパスカウントの下限値であるとはいえ、McCabe(1976)は経路複雑度を、カバレッジテストを100%行うのに要するテスト数の上限値であると指摘しました。
 
しかしこれを挑戦目標とするのは100%カバレッジテストを行うことよりも価値が無いと思われます。100%のテストカバレッジを行うとソフトウェア開発費をほとんど上回る結果となってしまい、基本的には不可能です。
 
QACはパスカウント500,000,000で測定を停止します。しばしばこうした膨大なパスカウントに達することもあります。こうしたコードは完全にテスト不可能であることを明記しておいて下さい。
STPDN パス密度。STPTH/STXLNで求めます。STXLNがゼロの時、STPDNもゼロとします。
STPBG パスに基づく潜在バグ見積。HopkinsはHatton&Hopkins(1989)の中で、スタティックパスカウントが、既知の検査済みのパッケージで見つかったバグの数をかなり正確に与えることを発見しました。STPBG = LOG10(STPTH)で求めます。
 

ファイルに関するメトリック

略 号 説 明 
STFIL ソースファイル名
STNAM ソースファイル名。関数ベース・メトリックとファイルベース・メトリックを別々のグループとして処理して統計解析するときに、QACツールセットの一部分で使用します。
STNTB 非トークンベースの統計用ヘッダ行。
STSCT 宣言したスタティック変数の数。この値が大きい場合は、ルーチン間で交わされるグローバルデータが多く、信頼性に副作用を与えることが示唆されており、コードの理解と変更が困難です。
 
グローバルデータが本当に必要な場合は、関連するデータを構造体として集めてグローバル変数の数を少なくすることも価値のある方法です。
STECT 宣言した外部変数の数。この値が大きい場合は、多くのグローバルデータがモジュール間で交わされることを示しています。たいていこれは常に劣った設計であることの証であり、各プロセスで要求されるデータが明確に識別されていないことも表しています。
 
二つのプロセスでデータを共有することが必要な場合、引数で渡すか、最悪でも関連データを一緒にまとめた構造体で行うべきでしょう。
STFNC このファイルで定義されている関数の数。
STFCO 関数カップリング(関数結合度)の概算。(関数カップリングについては Brandl-1990を参照)。
 
実際のBrandlメトリックの関数結合度の算出では、完全かつ十分に構造化されたコーリング・ツリーを必要とします。STFCOはBrandl値の概算です。
 
この値が大きいと、コーリング・ツリーのレベル間の複雑度に大きな変化が存在することになります。
STTKB トークン・ベース統計のためのヘッダ行。
STVAR このモジュールで使用されている識別子の合計数。
STOPT 区別可能な演算子の数(t1)。例えばキーワード、演算子、句読点などユーザが提供しないトークンも全て含みます。t1の値はZipf、Halsteadおよびその他の指標で使用します。
STOPN 区別可能なオペランドの数(t2)。ユーザが与える識別子、文字数で、これもまた Zipf、 Halsteadおよびその他の計算で使用します。
STTOT ソースファイル中の実際のトークン数(n)。
STZIP Zipfの手法を使用したnの予測。この値がSTTOTのnと2倍以上違う場合は、ソースファイルに普通にはない語彙が使用されています。
 
これは通常、ソースに同一あるいは非常に似た部分の繰り返しがあるか、語彙が異常に多いことを意味します。
 
いずれにしても形式上、普通ではありません。
 
計算式:(t1 + t2) * (0.5772 + ln(t1 + t2))
 
STHAL Halstead手法を用いたnの予測値。前項Zipfの予測で述べたことと同じ事がここでも当てはまります。
 
計算式:t1 * log2(t1) + t2 * log2(t2)
 
STSHN Shannonの情報容量。(エントロピーHとしてもまた知られています。)ビット換算でのプログラムの規模を見積ります。
 
STZIPからのトークン数の概算やトークンタイプの数を使用して計算します。プログラム規模を見積る際に広く見とめられている手法であり、比較測定として含まれています。
 
計算式:STZIP * log2(√(t1 + t2) + ln(t1 + t2))
 
STDIF プログラムの難易度。二つの異なるモジュールの相対的な難易度を理解するのに有効なメトリックです。平均的なCプログラムの難易度は約12です。これを大幅に越えるものは語彙が非常に多く、潜在的に理解が困難です。
 
計算式:1/L
ただし
L = (2 + STVAR) * log2(2 + STVAR) / STVOL
 
STEFF プログラム労力。モジュール作成に費やすプログラマの労力を示します。
STEFFおよびSTDIFは以下の開発時間の見積りを求めるときに使用します。
 
計算式:STVOL / L
 

 

STVOL プログラム規模。ビット換算によるプログラム規模の計算値です。実際のプログラムの長さ nを使用して求め、STEFFの計算でも使用されます。
 
計算式:0.5 * STTOT * log2(t1 + t2)    (v4.1以降)
 

 

STDEV ソースファイルを最初から開発する、あるいはもし必要なら、再開発するのに要する工数(人・日)の見積りです。 プログラム労力から導き出され、メトリックコンフィグレーションファイルqac.cfgで指定した係数が掛かります。コード行数だけに基づく Cocomo統計(以下を参照)と違い、この見積りは難易度係数を考慮しており、特に、組織固有のソフトウェア環境用にスケーリングファクタを調整すれば、しばしば実際の開発時間を正確に見積ります。
 
計算式:STEFF / スケーリングファクタ
 
STPRT 日換算でのポーティング時間の見積り。
 
一日あたりのポーティング量(単なるポーティングだけでなく、正常に動作するようにするまで)に上限と下限があるとの仮定のもとで、QACが発する警告数に基づいて要するポーティング時間を計算します。
 
上限と下限範囲、そしてスケーリング係数とも変更可能です。(詳細は、マニュアルのコンフィグレーションの章、qac.cfgを参照ください。)
 
計算式:STTPP / lpd
ただし
lpd = min_port + (1 - port) * max_port
port = (重み付け) / 100 * port_scaling
min_port、max_port、port_scaling、重み付けの3つの係数はqac.cfgで定義された値を使用。
 
STMOB 百分率による移植性-コードの‘モビリティ(移植度)’。STDEVとSTPRTから式(STDEV - STPRT) / STDEVで計算し、百分率で表示します。

 

 
例:

 

 
STDEV    10日
STPRT    0.8日
STMOB = (STDEV - STPRT) / STDEV = 92%

 

 
しかし、

 

 
STDEV    3日
STPRT    1.4日 の場合には、
STMOB = (STDEV - STPRT) / STDEV = 53% となります。
 
実際には大抵の Cコードは95%の移植度を持っています。これは C言語の特長である移植度の高さを表す証でもありますが、実際には言語自身の問題ではなく、マシンでサポートされているライブラリによって移植性の問題が数多く発生しています。
 
QACではこの点のチェックを‘callpack’とのコールシーケンスチェックとしてサポートします。
 

 

STBUG 語彙の解析によるバグ見積り。通常、この値はSTPBG統計の合計よりも小さな値です。ソフトウェアバグ見積りに関する詳細議論は、Hatton & Hopkins(1989)を参照ください。
 
計算式:STEFF2/3* 0.001
 

 

STTPP プリプロセス前のソース行の合計。Cocomo統計の計算で使用します。
STTLN プリプロセス後の合計行数。STTPPよりもほとんど常に小さな値になります。主に参考値として表示します。

 

 
STTLNとSTTPPが極端に違うときはCプリプロセッサの処理が多く、プリプロセッサに強く頼っていることを示しています。しかし、これは勧められないことが証明されるでしょう。

 

STBCS 基本的な Cocomo統計のヘッダ行。Cocomo統計の詳細は Boehm(1981)をご覧ください。QACはまた、時間見積りのCocomoコストモデルとソフトパッケージ全部のコストも提供します。

 

 
Cocomoコストモデルについては、マニュアルのレポートの章を参照ください。

 

STBMO “ベーシック”モデルの工数見積り(プログラマ・月)。コンポーネント間の結合度が小さく、比較的小規模のチームの個人が独自に開発するソフトウェアを想定。(COCOMOモデルで“Organic”と定義されている環境。以下、Organicと記載します。)
 
計算式:2.4 * K1.05
ただし、
K = STTPP / 1000
 
STBMS “ベーシック”モデルの工数見積り(プログラマ・月)。コンポーネント間のインタフェースが複雑で、例えばデータベースやWindowsアプリケーションなどに適用される。後述の組み込み型(Embedded)との中間的なもの。(COCOMOモデルで“Semi-detached”と定義されている環境。以下、Semi-detachedと記載します。)

 

 
計算式:3.0 * K1.12

 

 
STBME “ベーシック”モデルの工数見積り(プログラマ・月)。組み込み、リアルタイム制御用などのアプリケーションが対象。設計上の制約が多い。(COCOMOモデルで“Embedded”と定義されている環境。以下、Embeddedと記載します。)
計算式:3.6 * K1.20
STTDO “ベーシック”モデルの工数見積り(合計月数)。Organicモデルの場合。

 

 
計算式:2.5 * STBMO0.38

 

 
STTDS “ベーシック”モデルの工数見積り(合計月数)。Semi-detachedモデルの場合。

 

 
計算式:2.5 * STBMO0.35

 

 
STTDE “ベーシック”モデルの工数見積り(合計月数)。Embeddedモデルの場合。

 

 
計算式:2.5 * STBMO0.32

 

 
STCOM コメントベースの統計ヘッダ行。
STCDN コメント密度。コメント中の非ブランク文字数とコード中の非ブランク文字数との比率。この比率が大きい時はコメントが多すぎてモジュールが読みにくいことになります。(こうしたソースの中からコードを見つけ出すのは骨の折れる仕事です。)

 

 
また、比率が小さすぎる場合はコメントが少なすぎます。