Complexity in multiple dimensions
There are few metrics that serve as accurate of a touchstone for complexity than Cyclomatic complexity; yet, this metric alone can paint a somewhat misleading picture of true complexity because it doesn’t account for conditional depth.
For example, the following C++ code snippet yields a Cyclomatic complexity value of 5:
if(HighAmountAcct != NULL)
{
iMgrMemory->FreeUp(HighAmountAcct->GetHighPriorityMssgsResult);
}
if(AQuedAcct != NULL)
{
iMgrMemory->FreeUp(AQuedAcct->GetQueuedMessagesResult);
}
if(NotifyAcct != NULL)
{
AtlCleanupValueEx(&NotifyAcct->NotifyAcct, iMgrMemory);
}
if(ReplyAcct != NULL)
{
iMgrMemory->FreeUp(ReplyAcct->ReplyQueuedMessagesResult);
}
if(RegisterAcct != NULL)
{
AtlCleanupValueEx(&RegisterAcct->RegisterAcct, iMgrMemory);
}
Regardless of the domain or the language involved here, it’s hard to argue that this snippet of code is terribly complex. Each condition is logically separated– no one condition depends on another. Yet, compare the code above with the code below, which also yields a Cyclomatic complexity of 5:
if(ACCT_FAIL(iSettings->EnumValues(&iEnumValues)))
{
iSettings->Remove();
}
else
{
CHAR iActHldr[MAX_AMOUNT];
if(ACCT_SUCCEED(iEnumValues->Get(iActHldr)))
{
if(ccint(iActHldr, iName, len(iName)) == 0)
{
sr = iSettings->Delete(iName);
if (!ACCT_FAIL(sr))
{
sr = ACCT_FAIL(iSettingsMgr->Put(iSettings));
}
}
}
}
Again, ignoring the domain tackled here or the perceived complexity of the language, which code snippet do you find more complex? It’s clear that the second example snippet involves conditional depth, which means one must comprehend previous state in order to ascertain the context of an individual line of code– as you get deeper into a series of conditions, the management overhead increases as well.
While Cyclomatic complexity acts as an excellent barometer of complexity, as a stand alone metric, it’s one-dimensional– it only gives a partial picture. The addition of depth gives complexity a second dimension, which yields a far more explicit view. Keep in mind though, both method snippets are testing challenges– it’s just that the second snippet is arguably harder to test.

December 23rd, 2006 at 10:05 am
[…] Complexity in multiple dimensions- Yours truly muses on the inability of Cyclomatic complexity to accurately depict true complexity, man. […]
December 31st, 2006 at 2:25 pm
[…] Code conditionals like if and else clauses trigger complexity metrics like Cyclomatic complexity. The more conditions in a method, the higher the Cyclomatic complexity value– and the higher the value, the greater chance there’s a defect lurking somewhere the code (either presently or about to be coded). Granted, there are degrees of complexity associated with conditions too– the deeper the depth a series of conditionals reaches, the more complex it becomes compared to a linear sequential series of if clauses. […]
March 10th, 2007 at 1:05 pm
[…] If a particular tool doesn’t provide an automatic failure hook, you can easily build one– in fact, combining Groovy’s expressive scripting power with Ant makes this process quite easy. For example, you can audit a JavaNCSS (a software inspector that reports code size and complexity) report and fail a build if the maximum complexity (which is reported for individual methods) is exceeded. […]