Java: Complexity Measurement
Can programs measure source code complexity?
Because the complexity we're trying to measure is how complex a human programmer thinks a program is, it's unlikely that complexity measurement software will ever accurately model the human difficulties in comprehending source code, not to mention that there are lots of individual programmer differences.
Although no program can provide an accurate measurement of what a human perceives, there are some general rules of thumb that can make a rough estimation.
Measurements of whole programs, both from a design and after it has been written
- Function points are measurements of complexity in the design. From design information one can estimate the number of function points. The number of function points can the be used to estimate the size, effort, or schedule. See Function Point Analysis: Introduction for more information on this. This is not a technique which is useful for typical student programs.
- Lines of code. One of the most common measurements of complexity of a program is it's size. Size matters! Exactly what a line of code is has to be defined (eg, count statements and ignore declarations and comments). You will see this referred to as LOC (Lines Of Code) or SLOC (Source Lines Of Code).
Measurements of methods
An interesting topic is to measure the complexity of individual methods. There are several things that contribute to the complexity. For example.
- Visual size. Common advice is that a method that's larger than "a page" should be broken up. Although laughably gross, this measurement provides good advice.
- Lines of code. Another measurement that can suggest when to break up a large method, but doesn't give more guidance. Ignore comments and declarations when counting. You may see various acronyms for this such as LOC (Lines Of Code), SLOC (Source Lines Of Code), or NCSL (Non-Commented Source Lines).
- Number of operators and operands The amount of computation that a program does is reflected in the number of operators. Halstead proposed measures based on operators and operands. Although it measures complexity, it isn't so clear how to make use of this information. See Halstead Complexity Measures.
- Span complexity is a measurement of the distance between references to a variable. A larger span creates more short-term memory requirement. This seems more useful as a general coding guideline than as a numerical measurement. This intuitively supports the declare-at-first-use rule for local variables.
- Nesting depth is a measure of complexity. Less deep code is easier to read. Again, this is useful as a coding guideline.
- Coupling is the amount by which several modules (eg, classes) depend on others. The lower the coupling the better. There are several schemes for this, counting the number of methods that are called, number of classes that are referenced, coupling through parameters and globals, etc. A nice illustration of how this can be automated is Headway Software's Structure101, which I haven't used because of the high price, but there's a nice online demo that shows program visualizations at many different levels.
- Flow complexity is a very important part of the total complexity of a method.
There are two common measurements of flow complexity
- McCabe's Cyclomatic Complexity measurement is essentially a count of how many places the flow branches.
- Nejmah's NPATH complexity which is a count of all possible execution paths through a method, which means that nesting depth and boolean expression complexity in determining flow are used in this computation.
Simplifying control flow was the prime motivation for Structured Programming, which can be summarized most simply, but not especially comprehensibly, as the elimination of the
goto
statement. The ideals of structured programming have been so completely incorporated in modern programming that some newer languages, eg Java, don't even have thegoto
statement. The Java designers must have thought leaving outgoto
was risky becausegoto
is still reserved as a keyword, but is not used.
Computing McCabe's Cyclomatic Complexity for Java methods
Next: Method Cyclomatic Complexity describes how to easily compute the flow complexity of a Java method.