業務でコードの静的解析について調べていたら循環的複雑度(サイクロマティック複雑度:Cyclomatic Complexity)という「フローの複雑度」を評価する尺度に出会いました。コードの複雑さの比較性に優れた尺度だと感じてワクワクしたので紹介します。
定義
循環的複雑度の定義はいろいろありますが、そのうちのひとつは次のように定義されています。(wikipediaを参照しました)
グラフの終点ノードと始点ノードを結んだとき、循環的複雑度は、
ここで、
: グラフのエッジ数
: グラフのノード数
: 連結成分
簡単にいうと、エッジとノードで囲まれた領域の数です。
具体例
例1 『分岐1回』
if (c1) { t = 1; }
例2 『分岐先で分岐』
if (c1) { if (c2) { t = 2; } }
例3 『分岐の連結』
if (c1) { t = 1; } if (c2) { if (c3) { t = 3; } }
例4 『1重ループ』
for (int i = 0; i < n; i++) { t = i; }
例5 『2重ループ』
for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { t = i * j; } }
評価の目安
循環的複雑度は、10以下ならば良質なコード、30以上ならばバグが急に多くなるなどが言われているようです。リファクタリングやコード追加修正コストの見積もりなどの目安になりそうです。