52

Does function length affect the productivity of a programmer? If so, what is a good maximum number of lines to avoid productivity loss?

Since this is a highly opinionated topic please back up the claim with some data.

8
  • 8
    The length should not be measured in LOC, but in the amount of time required to comprehend precisely what it does. And that length, should be no more than a minute. If I can't figure it out in a few seconds, it's probably doing too much...after a minute, it definitely is.
    – CaffGeek
    Commented Dec 23, 2010 at 17:50
  • 5
    Your peer tells you after reviewing the code.
    – gnat
    Commented Apr 27, 2012 at 12:13
  • 17
    Maximum length should be 17.
    – ThomasX
    Commented Apr 27, 2012 at 12:29
  • 2
    Think S in SOLID. Commented Apr 27, 2012 at 12:29
  • 1
    @CaffGeek Or perhaps the function is simply doing something non trivial. I've seen functions which would take me days to fully understand. Even functions where I understand all the concepts involved can easily take half an hour to work through the details. While it's nice to have trivial functions, many problems are simply inherently difficult. Commented Jan 14, 2014 at 9:12

18 Answers 18

54

Since I embarked on this crazy racket in 1970, I have seen exactly one module that really needed to be more than one printed page (about 60 lines). I have seen lots of modules that were longer.

For that matter, I have written modules that were longer, but they were usually large finite state machines written as big switch-statements.

Part of the problem appears to be that programmers these days are not taught to modularize things.

Coding standards that maximize the waste of vertical space appear also to be part of the problem. (I have yet to meet a software manager who has read Gerald Weinberg's "Psychology of Computer Programming". Weinberg points out that multiple studies have shown that programmer comprehension is essentially limited to what the programmer can see at any given instant. If the programmer has to scroll, or turn a page, their comprehension drops significantly: they have to remember, and abstract.)

I remain convinced that a lot of the well-documented programmer productivity gains from FORTH were due to the FORTH "block" system for source code: modules were hard-limited to an absolute maximum of 16 lines of 64 characters. You could factor infinitely, but you could not under any circumstances whatsoever write a 17-line routine.

3
  • 4
    The whole philosophy of FORTH was designed to encourage this... You were intended to design your own vocabulary, relentlessly breaking up your program into smaller and smaller pieces, ending up with less of a script and more of a dictionary. Length-limits alone don't do it - you'll see a routine split into arbitrary pieces just to satisfy some coding standard. I think you're absolutely correct in suspecting that programmers are simply "not taught to modularize things"; this should have been one of the big wins of OOP, but for various reasons it's often de-emphasized as a goal unto itself.
    – Shog9
    Commented Dec 23, 2010 at 18:51
  • 1
    @Mr. CRT: The length limits in the block-oriented FORTH implementations FORCED modularization. The interactive nature of most FORTHs helps, by encouraging small modules and quick testing of those modules. D85, a file-based FORTH, did not force modularization, and I saw guys playing with D85 write a lot of run-on stream-of-programmer-consciousness forever modules with it. Hence my conviction. (For what it's worth, Liz Rather disagrees with me. She thinks it is mainly the interactivity that gives FORTH the productivity boost.) Commented Dec 23, 2010 at 23:38
  • 2
    +1 to introduce me the great book "Psychology of Computer Programming" :)
    – Samuel
    Commented Jan 2, 2013 at 14:49
38

What's the Right Size, Really?

Depends on the language you use, but in general (and for my personal taste):

  • Ideally, less than 25 lines.
  • Acceptably, less than 35 lines.

If it's more, then it's something I need to come back to later and rework.

But realistically, any size it needs to be when you need to deliver something and that it makes more sense on the moment to spit them out like that, makes it even easier sometimes for someone to review before shipping. (but still get back to it later).

(Recently my team ran a program on our codebase: we found class with 197 methods and another with only 3 methods but one of them was 600 lines. Cute game: what's the worse of the 2 evils?)


Now for a more zen answer... In general it's considered a good practice (TM) to quote one or two great men, so here goes:

Everything should be made as simple as possible, but not simpler. - A. Einstein

Perfection is finally attained not when there is no longer anything to add, but when there is no longer anything to take away. - A. de Saint Exupéry


Addendum on Comment Styles

As an addendum to this, your functions should have clear names explaining their intent. Regarding comments, I usually don't comment inside a function:

  • comments say "why?",
  • code says "how?".

A comment block at the top of each function (that requires explanation) is enough. If your function is small and function names are explicit enough, then you should just need to say what you want to achieve and why. I use inline comments only for fields in some languages or on block starts for functions that break that 25-35 line rules if the intent is unclear. I use a block comment inside the code when an exceptional situations occurs (a catch block where you don't need or want to do anything should have a comment saying why, for instance).

For more, please read my answer on Style and recommendations of commenting code

9
  • @haylem I guess this is programmer's version of Freddy vs. Jason :-)
    – Gaurav
    Commented Dec 18, 2010 at 16:09
  • i agree, however i would add it should be at the size of one screen page. if you have 72 lines in one screen page then the function should not exceed 72 lines. Commented Dec 19, 2010 at 10:00
  • @There's a matter of ensuring that a single function would hold in a screen page as well so as not to scroll, but that's usually not my primary concern. My concern is the amount of time it takes to process information when reading a function, and it's almost instantaneous if it's a clearly written one in 25 lines. It becomes just a matter of following the function calls. 72 is way too big for me (plus, what if you have split screens? And that would be dependent on the font. But I agree for the historical value of the recommendation)
    – haylem
    Commented Dec 19, 2010 at 10:10
  • 1
    Of course, sometimes you have functions where you just copy 70 different fields to 70 different places. I mostly use tt to generate these but sometimes you're stuck with a long-ass function (or a long ass-function) that doesn't really do anything of interest anyway so isn't a real problem. Commented Dec 19, 2010 at 18:25
  • 1
    When the function is e.g. Map(x => x.Property1); Map(x => x.Property2); Map(x => x.Property3); it's kind of clear that it's all quite the same. (Note this is just an example; this kind of function does pop up from time to time) Commented Dec 20, 2010 at 2:12
13

In my opinion, every function should be as small as possible. Each function should do only one thing and do it well. That doesn't really answer the maximum length question, but it is more my feelings on the length of functions.

To use the words of Uncle Bob, "Extract till you just can’t extract any more. Extract till you drop."

2
  • 4
    What do you mean by as small as possibly? Wouldn't being as small as possible be having each function just have two lines: one to do a single operation, and another that calls a function to do the rest?
    – Kelmikra
    Commented May 30, 2016 at 0:23
  • 1
    Uncle Bob again. Think for yourself. Don’t listen to uncles. They lead you astray.
    – gnasher729
    Commented Nov 10, 2019 at 11:14
12

A method that works for me is: Can I have a part of a longer function give a name that makes sense. I think length of a method is not that important like good naming. The method should do what the name says, no more and no less. And you should be able to give a good name. If you cannot name your method good, the code is probably not good put together.

1
  • 1
    And your method should do only one thing to have a good name... no 'And', 'Or' or anything else that make the method name 50 characters long.
    – Samuel
    Commented Jan 2, 2013 at 14:39
11

What should be the maximum height of a building? Depends on where the build is, or the height you want it to be.
You may get different answers from different people which come from different city.
Some script functions and kernel interrupt handlers are very long.

1
  • I'm totally agree with you. I like metaphors. :) A building of three floors may have been built by a fool architect who don't know where to put a valid safety exit and other building could have ten floors and be a perfect architectural design. We should always keep in mind that the readability and maintainability should be the main reason to refactor a method to reduce his size and not the size itself. A city could not be build with 90% of skyscraper except in science fiction movies. :)
    – Samuel
    Commented Jan 2, 2013 at 14:36
10

As long as it needs to be to do what it needs to do, but no longer.

2
  • as they say in c, "There is no problem in c that you could not solve by adding another pointer to that pointer." you could always add another function underneath it, his question would be to your epiphany "where does it end?" Commented Dec 19, 2010 at 10:04
  • 1
    I'd actually flip it and say "as short as it needs to be, but no shorter", but you get my +1 for being close enough :)
    – Ben Hughes
    Commented Dec 19, 2010 at 22:11
9

I think there is a trade off. If you have a lot of short methods, it is often harder to debug them than one long method. If you have to jump around the editor 20 or 30 different times to trace one method call, it will be hard to keep it all in your head. Meanwhile if there is one well written clear method, even if it is 100 lines, it is often easier to keep in your head.

The real question is why should items be in different methods, and the answer as given above is code re-use. If you aren't re-using the code (or don't know) then it may make sense to leave it in one giant easy to follow method and then as you need to re-use it, split the parts that need re-using into smaller methods.

In reality part of good method design is making functionally cohesive methods (essentially they do one thing). The length of the methods do not matter. If a function does one well defined thing and is 1,000 lines than it is a good method. If a function does 3 or 4 things and is only 15 lines, then it is a bad method...

3
  • I like short methods.
    – Marcie
    Commented Dec 19, 2010 at 13:55
  • 1
    I like what you said because saying that a method should not have more than 10 lines is in my view an utopia. Ok, it's a good rule to keep in mind each time you write a method but it's should not be a mathematic rule like 1 + 1 = 2. If you respect principles like KISS, DRY, YAGNI, etc... and your methods are not full a comments explaining some details because there are too long, methods can have 100 lines of code and could be totally clean to understand and maintain. However, it should be more an exception than a habit. I think switch case in factory method is a good example of exception.
    – Samuel
    Commented Jan 2, 2013 at 14:15
  • 1
    Many short methods are easier to test than one long method.
    – ethanneff
    Commented Mar 19, 2020 at 18:40
6

I find it easier to keep track of what I'm doing if I can see the entire function all at once. So here's how I prefer to write functions:

  1. Short enough to fit on my monitor with a reasonable font.
  2. If it needs to be longer than #1, short enough to print on a piece of paper in a reasonable font.
  3. If it needs to be longer than #2, short enough to print 2-up on a piece of paper.

I rarely write functions longer than that. Most of those are giant C/C++ switch statements.

1
  • Short enough to fit on a monitor is nice but specifying the font type and size. Paper should not be a rule in my view because we are in 2013 and who still print code on paper, who will print just to see if it fit on a paper size? With tools like Visual Studio, intellisense, there is no reason anymore to analyze code with paper.
    – Samuel
    Commented Jan 2, 2013 at 14:18
6

For me, a function is any length it needs to be. Most of the time that I divide it up is when I will reuse code.

Basically, I'll stick to the principal 'high cohesion, low coupling' and there is no constraint on length.

5

The question should be how many things should a function do. And usually, it's rare that you need a 100 lines to do "one" thing. Again that depends on the level from which you are looking at the code: Is hashing a password one thing? Or is hashing and saving the password one thing?

I would say, start with saving password as one function. When you feel that hashing is different, and you refactor the code. I am no expert programmer by any means, but IMHO, the whole idea of functions begin small is that the more atomic your functions are, the higher the chance of code re-use, never having to make the same change in more than one place, etc.

I have seen SQL stored procedures that run over 1000 lines. Does the number of lines of stored procedures also be less than 50? I don't know, but it makes reading the code, hell. Not only do you have to keep scrolling up and down, you need to give a few lines of code a name like "this does validation1", "this updates in the database", etc. - a work that the programmer should have done.

2
  • +1 for the first paragraph only. everything else is relative to the case you are working on. Commented Dec 19, 2010 at 10:05
  • And how does splitting it up into 50 functions help? When functions have to communicate, so you won’t finish with 500 lines but thousand?
    – gnasher729
    Commented Nov 10, 2019 at 11:17
5

From Cyclomatic complexity (Wikipedia):

The cyclomatic complexity of a section of source code is the count of the number of linearly independent paths through the source code.

  • I recommend that you keep that number under 10 in a single method. If it gets to 10, then it's time to re-factor.

  • There are tools that can evaluate your code and give you a cyclomatic complexity number.

  • You should strive to integrate these tools into your build pipeline.

  • Don't literally chase a method size, but try to look at its complexity and responsibilities. If it has more than one responsibility, then it's probably a good idea to re-factor. If its cyclomatic complexity increases, then it's probably time to re-factor.

  • I'm fairly certain there are other tools that give you similar feedback, but I didn't have a chance to look into this yet.

1
  • Cyclomatic complexity has been shown, on real code from one of the big public repositories, not contrived examples, to be very strongly correlated with raw SLOC. This makes it basically worthless, as it is far easier to count carriage returns. (Yes, it is possible to game SLOC. Be honest, here: How long would someone who was gaming the SLOC metrics at your employer be allowed to continue drawing a paycheck?) Commented Feb 7, 2017 at 0:05
4

Typically, I try to keep my methods/functions to what fits on the screen of a 1680x1050 monitor. If it doesn't fit, then use helper methods/functions to parcel out the task.

It helps readability on both screen and paper.

1
  • I do the same thing but its worth to specify which font type and size you are using. For myself, I prefer "consolas" with a size of 14 as suggested by Scott hanselman. hanselman.com/blog/… It's hard the first time to work with a so big font but it's a best practice to always remember you that your method should be the smallest as possible.
    – Samuel
    Commented Jan 2, 2013 at 14:03
4

I don't put a hard line limit on anything because some functions implement algorithms that are inherently complex and any attempt to make them shorter would make the interactions between the new, shorter functions so complicated that the net result would be no reduction in simplicity. I also don't believe that the idea that a function should only do "one thing" is a good guide, since "one thing" at a high level of abstraction can be "many things" at a lower level.

To me, a function is definitely too long if its length causes subtle violations of DRY right now, and extracting part of the function into a new function or class could solve this. A function may be too long if this isn't the case, but a function or class could easily be extracted that would make the code more modular in a way that is likely to be useful in the face of foreseeable change down the road.

1
  • 1
    Functions do "one thing" at a specific abstraction level, and you only worry about that one abstraction level. That's the whole point. If you can't grasp that, then I don't think you understand abstraction. Commented Oct 9, 2012 at 12:11
4

Short enough to be optimized correctly

Methods should be so short as to do exactly one thing. The reason for this is simple: so your code can be properly optimized.

In a JIT-ted language like Java or C#, it is important that your methods be simple so that the JIT-compiler can produce code quickly. Longer, more complicated methods naturally require more JIT time. Also, JIT compilers only offer a handful of optimizations and only the simplest of methods benefit from this. This fact was even called out in Bill Wagner's Effective C#.

In a lower-level language, like C or C++, having short methods (maybe a dozen or so lines) is also important because that way you minimize the need for storing local variables in RAM rather than in a register. (Aka 'Register Spilling'.) Note however that in this unmanaged case, the relative cost of each function call can be pretty high.

And even in a dynamic language, like Ruby or Python, having short methods also helps out in compiler optimizations as well. In a dynamic language the more 'dynamic' a feature, the harder it is to optimize. For example, a long method which takes an X and could return an Int, Float, or String will likely perform far slower than three separate methods which each only return a single type. This is because, if the compiler knows exactly what type the function will return, it can optimize the function call site as well. (E.g., not checking for type conversions.)

2
  • About 99.999% of the applications out there have much more things that slow down the speed of the programs like database access, file access or network latency. Thinking about the speed while designing methods could be a valid reason for gaming, real time application or reporting with tons of data but not in other cases. However, its a good point but as small as I am as a programmer, I rarely have to do this type of optimization in my applications.
    – Samuel
    Commented Jan 2, 2013 at 14:24
  • You do that kind of thing when you have measured the speed of your code and found it too slow, if you know what you’re doing (it’s not as simple as you think), and if you measure it afterwards and the speed has improved.
    – gnasher729
    Commented Nov 10, 2019 at 11:25
3

It very much depends on what's in the code.

I have seen a thousand-line routine that I had no problem with. It was a huge switch statement, no option exceeded a dozen lines and the only control structure in any option was a single loop. These days it would have been written with objects but that wasn't an option back then.

I'm also looking at 120 lines in a switch in front of me. No case exceeds 3 lines--a guard, an assignment and the break. It's parsing a text file, objects aren't a possibility. Any alternative would be harder to read.

2

Most compilers do not mind a function's length. A function should be functional, but be both easy to understand, change and reuse to human beings. Choose a length that suits you best.

1

My general rule is that a function should fit on the screen. There are only three cases I have found that tend to violate this:

1) Dispatch functions. In the old days these were common but most of them are replaced with object inheritance these days. Objects only work inside your program, though, and thus you'll still see occasional dispatch functions when dealing with data arriving from elsewhere.

2) Functions that do a whole bunch of steps to accomplish a goal and where the steps lack a good subdivision. You end up with a function that simply calls a long list of other functions in order.

3) Like #2 but where the individual steps are so small that they are simply inlined rather than called separately.

1

Maybe function length is not so a good metric. We try to use cyclomatic complexity, on methods too, and one of the future source control checkin rules that cyclomatic complexity on classes and methods must be lower than X.

For methods, X is set to 30, and that's pretty tight.

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