How to measure software
Software metrics are usually classified into product metrics, process metrics and resource metrics. Product metrics focus on finished artifacts like delivered software and documentation. Process metrics measure developer activities, development paradigms, tasks and milestones etc. Resource metrics measure inputs like people and hardware. Everything is measured: lines of code, binary size, number of classes/functions/interfaces, code coverage, commit history, documentation size, bug fixes, load time, performance, quality, reliability, cost, effort, usage etc. I'm mostly focused on direct metrics of available source code and executable itself: size and complexity.
Code size
This is the most straightforward and direct metric since it is based on counting lines of code. Counting lines of code (LOC) is de facto standard metric for the size of piece of software (or more accurately - program code). Variants on LOC are KLOC (kilo/thousands lines of code), MLOC (million lines of code) and SLOC (statement lines of code). Other measures can be based on LOC and provide more insight into analyzed source code, like number of errors per LOC etc. LOC-based metrics are popular because they are easy to compute and result in absolute measure of source code size. Alternative similar metric can be based on number of classes, methods or components. LOC is one of the most widely used metrics for developer contribution or productivity. Also, LOC per code commit or LOC per day are widely used metrics for developer activity.
Size metric like LOC is derived from static code analysis. Dynamic analysis during program run-time can be used for measuring "dynamic size" of running software. Dynamic size is closely tied to performance, e.g. number of objects, requests or transactions can provide valuable insights of software size or scale.
For those who are solely interested in LOC, popular web service Ohloh has large database of FLOSS projects along with statistics such as LOC, cost estimate and commit history. Also, check Wikipedia page about LOC.
Functional size
Functional size is calculated by quantifying the functional user requirements. Example of functional size metric is Function Point Analysis (FPA). FPA is used for estimation of project cost, duration and staffing size in early stages of development. FPA categorizes functions as data (internal files, external interfaces) or transactions on operating on accessing data (inputs, outputs or inquiries). For instance, external interface corresponds to data referenced (and not maintained by) application, while inputs are transactions where data enters the application. Since function point doesn't map to any physical attribute of a software, it is not easy to compute FP from program code or commit log. However, FPA is valuable because it measures software from user's perspective without being tied to specific technology.
For more info on FPA check this link.
Complexity
Complexity is usually defined as a degree of understandability and verifiability of some system. Although there are many other definitions of software complexity, I will focus on structural complexity (as opposed to psychological complexity) of static program code and dynamic execution graph. Software complexity is usually correlated with software size -- more LOC means more complexity (also, more complexity means more errors). McCabe metric and Halstead’s metric are historically important and commonly used code complexity measures. McCabe measures number of nodes and edges in directed graph derived from control-flow representation of the program. Halstead measures number of operators and operands and gives formulas for calculation of program volume, difficulty and effort (among others).
Other metrics include measuring structural complexity like number of directly invoked modules and number of inputs/outputs passed. These metrics include calculating fan-in (number of components that invoke current module) and fan-out (number of components directly invoked by current module). Coupling represents interconnections of code components. E.g. Information flow metric (INFO) calculates component usage as function of the number of calls into and out of an element. Opposite of coupling is cohesion or intradependence of code components (http://bit.ly/3rYNy). Besides already mentioned parameters, complexity can depend on software age, refactoring and maintenance process, coding style, tools used for development, experience of developers etc.
Dynamic complexity metrics are based on run-time execution of program code and they measure reference counts, dynamic trace analysis, loop executions etc. For instance, tools for profiling and tracing can find critical sections in program code and rank those sections by usage.
Good overview of code complexity is available here.
Tools
Here's a list of tools I compiled while I was gathering material for this post:
- CyVis - Software Complexity Visualiser
- GNU Complexity - Measure complexity of C source
- PyMetrics | Free Development software downloads at SourceForge.net
- Eclipse Metrics Plugin - State Of Flow
- Sonar
- ccm: analyzes c/c++, c# and javascript code
- C. M. Lott: Metrics tools for C/C++
- SLOCCount
- Collection: LOC Metrics - Alternative Tools
- Collection: Software Testing FAQ: Static Analysis Tools
Trends
I'm interested in general trends in software. Software today is based on layering principle where each component depends on layers (or stack) below. This pyramidal structure of one abstraction over another has tendency of software size reduction as abstraction grows. Program code is obviously getting smaller going up this pyramid; progression from Linux kernel and its 15 million lines of code to mobile applications and then to some small mashup script is clear evidence of this trend. Of course, components in layers themselves are becoming bigger; for instance, Linux kernel grows at rate of approximately 1 MLOC per year (http://bit.ly/X5LZB and http://www.ohloh.net/p/linux).
What about complexity? Complexity of whole stack is increasing. If for nothing, then for mere size of entire software pyramid. Structural (and psychological) complexity is decreasing going up the pyramid. You will probably need less time, experience, components (operators, data structures, functions...), interconnections and interfaces for web development than for kernel development.
With decreased size and less complexity more developers are able to join the game. With millions of developers arises question of developer contribution. More on that in next post.

