Search code examples
javascriptperformanceeslintcyclomatic-complexity

in the sake of increasing code performance... ESLint is reporting "Arrow function has a complexity of 21. Maximum allowed is 20"


ESLint reports an intolerably high complexity. I want to know why is it too complex? And what happens if I just split it into multiple functions - is that performant? As I know we always have to write minified code so if we split it into multiple functions it will consume more space (bits) and more execution time?
And what is the best practice to deal with this snippet.

const getWeekType = (f, d, e) => {
  const y = moment(),
    a = moment(f),
    i = moment(d);
  if (d && f && i.diff(a, 'days') <= 8 && y.diff(a, 'days') < 8 && y.diff(a, 'days') >= 0) {
    return { weekNum: 0, dayNum: y.diff(a, 'days') };
  }
  if (f && y.diff(a, 'days') >= 0 && y.diff(a, 'days') < 8 && (!d || i.diff(a, 'days') > 8)) {
    return { weekNum: 1, dayNum: y.diff(a, 'days') };
  }
  if (d && !f && i.diff(y, 'days') >= 0 && i.diff(y, 'days') < 8) {
    return { weekNum: 2, dayNum: 6 - i.diff(y, 'days') };
  }
  if ((!f || y.diff(a, 'days') > 8) && (!d || i.diff(y, 'days') > 8)) {
    let d = y.diff(f ? a : moment(e), 'days');
    for (; d > 7; ) d -= 7;
    return { weekNum: 3, dayNum: d };
  }
};

Solution

  • Two issues:

    • Variable names are meaningless
    • Several calls to diff are repeated

    I don't really have an idea what the code is supposed to do, but here is a sketch of what it could look like:

    const getWeekType = (start, end, alternative) => {
      const now = moment(),
        startMoment = moment(start),
        endMoment = moment(end),
        days = endMoment.diff(startMoment, 'days'),
        daysPast = now.diff(startMoment, 'days'),
        daysFuture = endMoment.diff(now, 'days');
            
      if (end && start && days <= 8 && daysPast >= 0 && daysPast < 8) {
        return { weekNum: 0, dayNum: daysPast };
      }
      if (start && daysPast >= 0 && daysPast < 8 && (!end || days > 8)) {
        return { weekNum: 1, dayNum: daysPast };
      }
      if (end && !start && daysFuture >= 0 && daysFuture < 8) {
        return { weekNum: 2, dayNum: 6 - daysFuture };
      }
      if ((!start || daysPast > 8) && (!end || daysFuture > 8)) {
        let dayNum = start ? daysPast : now.diff(moment(alternative), 'days');
        return { weekNum: 3, dayNum: dayNum % 7 };
      }
    };