This document discusses code complexity and how to measure it objectively using cyclomatic complexity. Cyclomatic complexity is a metric developed by Thomas McCabe that measures the number of linearly independent paths through a program's source code. It is calculated as the number of edges (flow control statements) minus the number of nodes (executable statements) plus 1. The document provides examples of functions with different complexities and discusses how complexity scores can help prioritize testing and refactoring efforts.
1. Code
Complexity 101
Arun Saha, Ph.D.
arunksaha AT gmail DOT com
(A pragmatic programmer and a software craftsman)
https://www.linkedin.com/in/arunksaha
3. (Bitter) Fact of life:
Code complexity keeps increasing
What
November 2014 Code Complexity 101 3
4. (Bitter) Fact of life:
Code complexity keeps increasing
What
November 2014 Code Complexity 101 4
How to measure code complexity
objectively?
5. Simple Objective Metric:
Cyclomatic Complexity
What
November 2014 Code Complexity 101 5
Developed by Thomas J. McCabe Sr. in 1976
Also known as McCabe Complexity
Definition and Theory: http://en.wikipedia.org/wiki/Cyclomatic_complexity
6. Cyclomatic Complexity of a Function,
M = E – N + 1
Where, E = # of edges, N = # of nodes
Details
November 2014 Code Complexity 101 6
if (c1())
f1();
else
f2();
if (c2())
f3();
else
f4();
M = 9 – 7 + 1 = 3
7. Informally,
Complexity of a module*:
sum of complexities of its functions
* e.g. *.c, *.cc file
November 2014 Code Complexity 101 7
What
8. Complexity of a function:
M = E – N + 1
How
November 2014 Code Complexity 101 8
Lower bound:
# of conditionals
For example, in C and C++, each of the following keywords increase the
complexity by 1
return, if, for, while, &&, ||, ?:, case,
goto, break, continue
9. FYI
November 2014 Code Complexity 101 9
however,
Calling function does not increase complexity of either
the caller or the callee
10. FYI
November 2014 Code Complexity 101 10
however,
Calling function does not increase complexity of either
the caller or the callee
11. Caveat
November 2014 Code Complexity 101 11
McCabe Complexity != Big O Complexity
They are totally completely different.
12. Example 1
// Two functions of complexity 1
int c1_direct( int x ) {
return x + 1;
}
int c1_redirect( int x ) {
int const result = add( x, 1 );
return result;
}
E.g.
November 2014 Code Complexity 101 12
13. Example 2
// complexity: 2
// 1 for “return”, 1 for “?:”
int c2_min( int x, int y ) {
return y < x ? y : x;
}
E.g.
November 2014 Code Complexity 101 13
14. Example 3
// complexity: 3
// 1 for “if”, 1 for each “return”
int c3_min( int x, int y ) {
if( y < x ) {
return y;
}
else {
return x;
}
}
E.g.
November 2014 Code Complexity 101 14
15. Example 4
// complexity: 3
// 1 for “return”, 1 for “&&”, 1 for “?:”
int c4_bothtrue( int x, int y ) {
return (x && y) ? 1 : 0;
}
E.g.
November 2014 Code Complexity 101 15
16. Same function can be (correctly) written with different
complexities.
FYI
November 2014 Code Complexity 101 16
17. Example 5.1
Problem BothNonZero: Given two int’s, return
non-zero if both are non-zero, zero otherwise.
// BothNonZero: Approach 1, Complexity: 4
int bothNonZero_1( int x, int y ) {
if( x ) {
if( y ) {
return 1;
}
}
return 0;
}
E.g.
November 2014 Code Complexity 101 17
18. Example 5.2
// BothNonZero: Approach 2, Complexity: 4
int bothNonZero_2( int x, int y ) {
if( x && y ) {
return 1;
}
return 0;
}
E.g.
November 2014 Code Complexity 101 18
19. Example 5.3
// BothNonZero: Approach 3, Complexity: 2
int bothNonZero_3( int x, int y ) {
return x && y;
}
E.g.
November 2014 Code Complexity 101 19
20. FYI
November 2014 Code Complexity 101 20
A common application is to compare the measured
complexity against a set of threshold values. One such
threshold set is as follows
Cyclomatic Complexity Risk Evaluation
1 – 10 A simple program, without much risk
11 – 20 More complex, moderate risk
21 – 50 Complex, high risk program
51 + Unstable program (very high risk)
Source: http://www.sei.cmu.edu/reports/97hb001.pdf p. 145
Fine, but how complex is really complex?
21. Dev Team:
Where should I
prioritize my
refactoring?
Benefits
November 2014 Code Complexity 101 21
QA Team:
Where should I
prioritize my testing?
22. FYI
November 2014 Code Complexity 101 22
I use CCCC
http://sourceforge.net/projects/cccc/files/cccc/3.1.4/
with my simple wrapper mccabe.sh
(available at)
https://github.com/arunksaha/complexity
(contains the function examples used here)
Great, how can I get started today?