Code cyclomatic complexity optimization

What is cyclomatic complexity

Cyclomatic complexity is the number of independent linear paths that can be used to measure the complexity of a module to determine the structure. In the simplest case, if a function has an if else statement, there are two paths to execute the function, one if and the other else, and then the cyclomatic complexity of the function is 2.

The higher the cyclomatic complexity, the lower the maintainability and complexity of the code, the higher the cost of testing and the more problematic the code. What we need to do is optimize the code to reduce cyclomatic complexity and make it easier for developers to understand and maintain.

Cyclomatic complexity is also a measure of the code quality of a project. In large projects, there are certain requirements for cyclomatic complexity, beyond which there may be an alarm state. Therefore, cyclomatic complexity should be paid attention to by every developer.

Cyclomatic complexity is a common optimization type

  1. Algorithm to optimize
  2. Expression logic optimization
  3. Big functions split into small functions

Cyclomatic complexity optimization comparison

Reduce unnecessary branches

Here’s an example of an if else statement that you wouldn’t normally write if you were a beginner, but here’s an example.

// bad
const env = "dev";
if (env === "test") {
    // do something 
} else if (env === "dev") {
    // do something 
} else if (env === "online") {
    // do something 
} else {
    // do something 
}
Copy the code

I remember the first time I worked on campaign H5 I had this code, and it felt awkward when I finished writing it, so I made a change. Instead, use the Swtich method:

// bad
switch (env) {
    case "dev":
        // do something 
        break;
    case "test":
        // do something 
        break;
    case "online":
        // do something 
        break;
    default:
        // do something 
        break;
}
Copy the code

However, this optimization actually just feels a little better, there are not so many if and else, but only focus on the function of each case. It looks a little cleaner, but the cyclomatic complexity is still the same. Therefore, it needs to be changed into:

// good
const env = "online";
const list = {
    dev: pageDevEvent,
    test: pageTestEvent,
    online: pageOnlineEvent,
};

list[env]();
Copy the code

The cyclomatic complexity is greatly reduced, no matter how many configurations are added to the list, its cyclomatic complexity is 1.

Expression logic optimization

The increase of expression logic calculation also increases the cyclomatic complexity, and optimization of some complex logical expressions can reduce the cyclomatic complexity to a certain extent. For example:

// bad
const version = 4;
const client = "iOS";
if (
    (client === "iOS" && version > 2) ||
    (client === "And" && version > 3)) {
    //do something
    console.log("11");
}
Copy the code

Through optimization judgment, it was changed to:

const isHighVerIos = client === "iOS" && version > 1;
const isHighVerAnd = client === "And" && version > 2;

if (isHighVerIos || isHighVerAnd) {
    //do something
}
Copy the code

Here’s another example, one I’ve seen recently and jotted down. Although, I was surprised, but actually business code does not know whether to write this, this writing is actually a little bit different.


// bad
const eventName = "dev";
if (eventName === "dev" || eventName === "test") {}Copy the code

Check whether corresponding parameters are included by using the includes method

//good
const eventName = "dev";
console.log(["dev"."test"].includes(eventName));
Copy the code

Let’s give it a try. I think I can rewrite it, because it’s not quite the same as before, and it’s going to look a little bit tough.

Reduce return occurrences

//bad
function next(){
    const env = getBoolen();
    if(env){
        return true;
    }else{
        return false; }}//good
function next(){
    return getBoolen();
}
Copy the code

It’s important to note that there are more than one cases where a return can be used. A function can only return 1 or 2 at most. If several returns are set, there is a problem with the code, and even if there is no problem, it will look uncomfortable.

Auxiliary tool

You can use ESLint to help check the cyclomatic complexity of your code, and errors will be reported if a certain value is exceeded

"complexity": ["error", { "max": 8 }]
Copy the code

If the value exceeds 8, an error message will appear.

Please follow GavinUI by scanning the QR code on my official account.