1

I'm looking for a code metric for monitor and track over time the size of several projects and their components.

Also, I would like to use it for:

  • evaluate size reduction after refactoring
  • compare the size/length of two implementations of the same specification, even across languages.

I know there are cyclomatic complexity and ABC metrics for complexity, but in addition to that I want a separate metric about the length/size/volume/extension of some code regardless of their complexity.

Being aware of the advantages and disadvantages of SLOC, I wouldn't use it for these purposes, mainly because I'm trying to measure code that is in different styles or languages.

For example this method body has 3 SLOC:

  public static String threeLines(String arg1) {
    String var1 = arg1 + " is";
    String var2 = var1 + " something";
    return var2;
  }

Also this one:

  public String otherThreeLines(String arg1) {
    IntStream stream1 = Arrays.stream(arg1.split(";"))
      .sequential()
      .map(s -> s.replaceAll("[element", ""))
      .map(s2 -> s2.replaceAll("]", ""))
      .mapToInt(Integer::parseInt);

    double var1 = stream1.mapToDouble(Double::new).map(d -> d / 2).sum();

    return String.valueOf(var1);
  }

Clearly, the second one is "bigger" or "longer", has more to read and think about, so I would like it to have a higher value in the metric.

There is no aim to evaluate if some piece of code is good or bad because of this metric, it's just for statistical analysis.

It would also be nice if it were simple to implement, without the need to fully parse file language.

So, I'm thinking of counting identifiers, keywords, and operators. for example this fragment

String var2 = var1 + " something";

could be analyzed as [String] [var2] [=] [var1] [+] [" something"]; and have a score of 6

And this fragment from the second method:

double var1 = stream1.mapToDouble(Double::new).map(d -> d / 2).sum();

could be analyzed as [double] [var1] [=] [stream1].[mapToDouble]([Double]::[new]).[map]([d] [->] [d] [/] [2]).[sum()]; and receive a score of 14

So the size/length of the second one should be roughly 2x of the first one.

Are there any known code metrics that would show similar results?

3
  • 2
    Wouldn't this penalize creating temporary variables that increase readibilty, even if they get optimized out by the compiler?
    – Llewellyn
    Sep 6, 2020 at 20:16
  • yes it would, thanks for pointing it out @Llewellyn. Maybe other practices that makes code more clear will be penalized too. In order to get a whole picture I think a size metric like this should be evaluated together with other metrics for complexity. There are like two dimensions, I think. Counting operators as Christophe suggested would be better regarding the temporary variables.
    – Guish
    Sep 6, 2020 at 20:48
  • I'm honestly not sure of a single use-case where such a metric would be useful, besides code golf. This pushes you towards code like a=>a[a.map((e,i)=>!e&&(t=0,a.map((e,j)=>t+=(j-=i)&&e/j/j),t<m&&(m=t,k=i)),k=0,m=1/0),k]=1
    – Alexander
    Sep 8, 2020 at 15:58

1 Answer 1

2

Indeed, the SLOC is used for simplicity and does not fully express the real complexity of code.

Use of increment, ternary or comma operators, or multiple statements are a phenomenon that significantly impacts the SLOC count (in one direction), whereas comments, clean functional decomposition and access control, also have an influence (in the other direction). Moreover, the design effort behind nice reusable OO code is not the same as copy/pasting pieces of code in several places.

So, whatever measurement you use, it will never be fully representative of the effort and will always have some bias. Even more if such indicators are promoted to performance indicators.

This being said, and remaining aware of their limitations, indicators can help:

  • The cyclomatic complexity goes further than your counting approach, since it also analyses the complexity of the control flow in a function/module.
  • OOP has significantly affected the relevance of such analysis. Chidamber&Kemerer’s CK set of metrics could therefore be an interesting start: it uses methods per class, depth of inheritance tree, coupling between classes and similar factors that express some facets of the complexity of OOP deliverables.
  • another set of metrics is the MOOD which also analyses inheritance, coupling and polymorphism, but also encapsulation

Most of these methods calculate size-independent indicators. But these are based on some measurable quantities which could be if interest for you.

5
  • I will take a look at CK and MOOD, it is very interesting and I would like to know more about static analysis and code metrics. I also considered cyclomatic complexity for other purposes, but in this question I'm trying to measure something like the "length" of some code. for example a method could have a lot of simple assignments, let's say 50, with no control structures, no ifs. if there is other method with the same structure, low complexity but fewer instructions should be measured as shorter by this metric.
    – Guish
    Sep 6, 2020 at 15:41
  • @Guish I understand. But if the structure is comparable, and only the length matters, a simple statement count (or the more elaborate operator count) will do: if you have more temporary identifiers but in the end, less operetors, the number of identifiers won’t make a difference. By the way, lore identifiers means more declaration statements, so counting identifiers will weight twice. Now the question is how you would count the import/include which always count for one line, regardless of it containing 1 or 1000 classes/interfaces the code is relying on.
    – Christophe
    Sep 6, 2020 at 16:08
  • I'm planning to ignore all import/include statement and comments for this metric. Other way to see what I try to achieve is "how much sould I read in this file", regardless of the complexity. It could be perceived also like the volume or extension of a program.
    – Guish
    Sep 6, 2020 at 16:21
  • counting operators seems to be also a good fit. thanks for the suggestion @Christophe. I applied to some examples and give me numbers that I could consider representative for what I was thinking.
    – Guish
    Sep 6, 2020 at 16:32
  • While mentioning cyclomatic complexity, it might be a good idea to mention the cognitive complexity, too.
    – Andy
    Sep 7, 2020 at 11:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.