Does my method look big in this?


How big is the following Java method?

    public Collection getDescription() {
	SystemLibrary systemLib = registry.get(SystemLibrary.class);
	Analysis analysis = systemLib.getCurrentAnalysis(registry);
	return getDescription(analysis);
    }

This humble method locates some sort of system library, retrieves an Analysis, and returns a description of that Analysis.

But how big would you say it is? Would you say it is 3 lines of code long? If so, would you say the following behaviorally equivalent method is 2 lines of code long? And is it better because it's shorter?

    public Collection getDescription() {
	Analysis analysis = registry.get(SystemLibrary.class).getCurrentAnalysis(registry);
	return getDescription(analysis);
    }

Or would you say that the above two variations are the same size because both essentially call the same methods?

Or that they are the same size because both have three responsibilities, regardless of formatting.

Or because they have just one responsibility: the returning of an analysis description?

Method-size confusions arise and matter. They arise because projects fail to agree at the outset an objective unit with which to measure size. They matter because keeping methods small is the most foundational of the SIPT structural principles for which objective evidence of cost-reduction exists - the correlation is weak but statistically significant.

One non-intuitive measure of size worth considering is the amount of bytecode to which the method compiles.

Wait! Before killing that browser and uninstalling it forever, consider ...

Of course, few Java programmers would know or care that the above method compiles to 35 bytes (it does). But using bytecode has the tremendous double-advantage that it's utterly objective (programmers need never-again mud-wrestle over whether a method is 2- or 3-lines long) and scripts and parsers can harvest the information automatically and continuously.

Nor do programmers ever have to learn how to do anything as ludicrous as compile Java in their heads.

Let's say your project agrees to limit method size to 50 bytes. Deborah quickly - within minutes - finds that 50 bytes is roughly 5 lines of code by her traditional standard of measuring a line. So she keeps her methods 4 lines of code long, and the project's size-goons never have to knock on her door. (See if you can develop this skill in under a minute, here.)

Danny, on the other hand, finds that 50 bytes is 6 lines of code, according to his programming style, so keeps his methods 5 lines long. As long both satisfy the script (and associated automated weaponry) that parses the compiled code every check-in, then project managers can slumber on, knowing that quality - for this particular code property at least - is secure.

Of course, sometimes methods mirror their masters and begin bulging at the waist. When method-size starts increasing, the policy by which your project interprets statistics becomes decisive.

Practical projects understand the importance both of small methods and of trusting programmers with some flexibility. Practical projects do not require that all methods be small, only that they be small on average and that - even more importantly - this average does not trend upwards unbounded.

Let's say a project decides that the average method must be less than 50 bytes long. Then, if the average method size hovers at 47 bytes long, the project might allow a team to commit slightly larger changes, bringing the average to 48 bytes long. (Though some programmers take pride in never, never increasing the average method size, no matter how low it is.)

But the project will not - must not - allow any team to drag that figure to 50 bytes long or longer.

50 bytes?! You crazy!

Do you think 50 bytes (say, 5 lines of code) too small? Do you think it impossible that any large Java software project could have so small an average method size?

Does your project use Jenkins? The average of Jenkins' 15,089 methods is just 29 bytes long. That's roughly 3 lines of code.

In fact modern projects have little problem keeping to low thresholds. Table 1 shows a list of popular Java programs and their average method sizes in bytecode.

Program Average method size (bytes) Program Average method size (bytes)
Netty 20 ActiveMQ Broker 32
JUnit 23 Spring 40
Camel 27 Log4J 40
Jenkins 29 Tomcat (coyote) 44
Spoiklin Soice 29 Cassandra 53
Struts 30 Lucene 55
FitNesse 31 Zookeeper 55
Maven 35 Catalina 57

Table 1: Average method sizes in bytecode.

If anything, 50 bytes may be too generous. Perhaps 40 bytes would be better. Or 30.

Summary.

Size matters because large methods cost more than smaller methods.

It's not the only thing that matters - a host of other foundational structural principles wait in the wings - but it handsomely repays effort invested in keeping it under control.

The selection of an objective and automated measurement process - as well as general agreement on a threshold value above which no one must rise - ensures such investment bears fruit.