21

Functions are not only used to minimize duplication of code - they are also used to split up a long function into smaller ones to increase readability, as well as making the code self-commenting. Yet this gain is not directly inversely proportional to the number of LOCs per function or method; otherwise we would have tonnes of functions, all of which only contains a single line or two of code.

This lead me to wonder: Does there exist an optimal number of LOCs per function? If so, what is it, and does it deviate between languages?

gablin
  • 17,407
  • 6
    See Code Complete Vol 2 by Mitch McConnell Chapter 7 Section 4 for a good time. – Peter Turner Oct 04 '10 at 21:11
  • 2
    @Peter - I think you mean "Steve McConnell" – JohnFx Oct 04 '10 at 22:40
  • Yeah, funny I'd write that while looking at the book.... Wasnt Mitch McConnell Pres. Bush's chief of staff? – Peter Turner Oct 05 '10 at 03:35
  • 3
    The number almost certainly varies by language: I would be surprised to see a 6-line Prolog clause, while being perfectly OK with a 20 line Delphi method. My answer below's for Smalltalk, which uses the environment to encourage short methods. – Frank Shearar Oct 05 '10 at 06:12
  • @Peter Turner: Oh yeah. Had forgot about that section. I need to reread Code Complete some time. – gablin Oct 05 '10 at 17:57
  • @gablin, I just put my copy on my office-mate's desk with dollar bills taped to ch7.4, when he gets back from vacation tomorrow we'll have a nice chat about his 30 temp variables and 4,400 line function. – Peter Turner Oct 05 '10 at 18:33
  • @Peter Turner: Haha! Be sure to tell us how it went. ^^ – gablin Oct 05 '10 at 18:43
  • @gablin, he just laughed and I looked like a jerk. He at least admitted he has a problem with his temp variables, S1 through S15 and I1 through I11. – Peter Turner Oct 06 '10 at 13:21
  • 1
    @Peter Turner: Hm... S1 through S15 and I1 through I11. Sounds like he's confusing temporary variables with registers. ^^ – gablin Oct 06 '10 at 14:55

7 Answers7

34

Instead of number of lines, the criteria I would use is that each function should do only one thing and does it well.

grokus
  • 7,528
  • Yes, if we have a unit of work I don't want to have to move between 50 functions to get the jist of what is happening. If you break out your functions appropriately using this metric they should almost naturally be reasonable in size. – ChaosPandion Oct 04 '10 at 20:53
  • 2
    @ChaosPandion: but your unit of work may be probably expressed as a sequence of more elementary steps. If you are reviewing the function, you will review the sequence of steps, not the code of each single step. – Wizard79 Oct 04 '10 at 21:14
  • 2
    @Lorenzo - If that is the case each step becomes the unit of work. The parent function becomes a high level overview of the units of work. – ChaosPandion Oct 04 '10 at 21:26
  • 1
    Yes, this is very true indeed. Hm, let me rephrase the question then: Is there an optimal number of LOCs for functions which does only one thing, and does it well? – gablin Oct 05 '10 at 05:01
  • @gablin, hard to say and also LOCs is language dependent, but if you adhere to this principle, usually you end up within a reasonably range, say 1~50. – grokus Oct 05 '10 at 14:52
  • Even better if the function does nothing, but just tells what the result is. – Ingo Mar 18 '13 at 00:18
  • Another criteria is that the function is testable. Even if you don't actually write a test (although you should) you should be able to define the expected output for the input. Using a 'testability' approach discourages a lot of conditional/branching logic which can be hard to follow because the tests would be very hard to write. – ipaul Mar 18 '13 at 02:44
21

An old thumb rule is that a function should be entirely visible on screen, without the need of scrolling.

The basic idea is that, if you can't look at the whole function at a time, the function is over complex, and you should split it in more basic pieces.

While this rule is very practical and useful, the formal rule is that you should keep only a single logical step in a function. A function does just an elementary job, if you can divide the job in more elementary pieces, the function has to be split.

Wizard79
  • 7,357
  • 22
    This metric becomes progressively more useless as average monitor size/resolution increases. – Adam Lear Oct 04 '10 at 20:40
  • 2
    Our programming prof just said this example the other night :) – cdnicoll Oct 04 '10 at 20:41
  • 2
    @Anna: well, my monitor is high res but also the number of toolbars/palettes/panel has increased. And then, now I can use 14 pt pitch font! :) – Wizard79 Oct 04 '10 at 20:43
  • 4
    The 24 x 80 size of a terminal doesn't tend to change. – alternative Oct 04 '10 at 21:31
  • I'd say this no longer matters if you can collapse structural elements in your IDE. Also, this would speak for 200 characters / line. – peterchen Jun 28 '11 at 12:16
  • The original observation was one printer page (about 60 lines, typically around 130-some characters per line). I've been in this crazy racket in one capacity or another since about 1970, and I have seen exactly ONE (1) module that NEEDED to be bigger than that. (It was the photon torpedo routine in the Matuszek-Reynolds-McGehearty-Cohen STARTRK game, written in CDC 6600 FORTRAN.) I have yet to find a monitor that really gives me 60 lines on the screen (closest so far was 50-line VGA mode) and is still readable, and I'm notorious for using eyestrain fonts. – John R. Strohm Feb 15 '12 at 21:59
  • @JohnR.Strohm I use vim on a 1280x1024 monitor and get about 70 lines visible on the screen at once. I think it's around 14pt font size (characters are 20 pixels high according to my selection in xfontsel - which, doing the math, doesn't quite add up. They are smaller in vim than in xfontsel, though) – Izkata Feb 15 '12 at 22:29
  • @Izkata: That sounds about right. The 1280x1024 monitors I've used were all small enough that the eyestrain fonts to get that many lines on the screen were almost unreadable. At 56, my eyes are not what they used to be, not that they ever were... My worst-ever was when I REALLY needed to see 64 lines of 64 3-digit numbers all at once. I was working on a low-end video target tracker, and needed to see the image data it was processing, in number form - MAJOR PAIN. – John R. Strohm Feb 15 '12 at 23:58
  • This rule is no longer practical nor useful IMO. Screens are considerably bigger, but the general consensus on a good size for functions remains fairly constant. – Bryan Oakley Feb 16 '12 at 22:14
  • @JohnR.Strohm: you need a bigger monitor! My emacs window is regularly a little over 80 lines of fairly large text (roughly 12 points). Admittedly I usually have it divided such that the main area I work in is typically 70 lines tall. – Bryan Oakley Feb 16 '12 at 22:20
  • 1
    nonsense, the point of the rule is "can you see it all without scrolling". With a big monitor you can have more in your function without violating this rule, it doesn't mean big monitors are only allowed to view small functions (though with all the toolbars and property windows your IDE has, this probably still holds true :-) ) – gbjbaanb Feb 16 '12 at 23:31
  • Please define elementary job – user877329 Sep 13 '12 at 12:18
  • A long time ago, I think this limit was usually around 26 lines, give or take. If you take that number and try to keep up with that number, instead of the actual monitor size, there's still some life in this for more traditional, general-purpose languages. Still, I think it's less a question of LOC and more a question of what the function's actually doing. – Panzercrisis Jul 31 '15 at 13:23
15

There is none.

Screens are getting bigger, font sizes smaller. Rules of thumb don't work so well when people have different sized thumbs.

Be concise. If your function does multiple things it's probably a good idea to break it up into smaller ones.

Robert Harvey
  • 199,517
Josh K
  • 23,029
6

Smalltalk has a slightly unusual way of reducing the size of methods. When you write code, you write it in a widget called a Browser. A Browser has two main parts, divided horizontally. Your code goes in the bottom half.

By default, a Browser's not very big. You can fit 5 or 6 lines in before you'll need to start scrolling. Scrolling, of course, is slightly irritating.

So in Smalltalk the environment "encourages" you to write short methods, of at most around 6 lines in length. (That's usually plenty; Smalltalk is a pretty terse language.)

Frank Shearar
  • 16,683
2

The ideal number of lines of code in a method is variable. Basically, you only want to write just enough code to do what needs to be done within the context of the function's definition. I think of this as a kind of Single Responsibility Principle, only applied to a method instead of a class.

Where a method has a lot of logic, and a number of steps to complete, then it makes sense to break the method up into several discrete steps. Each of these steps would be extracted into new methods as required.

"otherwise we would have tonnes of functions, all of which only contains a single line or two of code."

The less each method does, the more easily defined it is, and the simpler to understand and manage. There is nothing wrong with having hundreds of methods if you need them. Also, in keeping with the SRP I mentioned earlier, it becomes easier to extract new classes when the methods have been teased apart into smaller and more manageable pieces.

S.Robins
  • 11,485
  • 3
  • 37
  • 52
1

The answer is of course 42.

Important to note: No funcion may ever violate the SRP, or you have to face the spanisch inquisition.

A few hints how to reduce the ammount of lines:

  • Are there comments marking individual sections? Those sections should be functions.
  • Are there if-else chains or switch statements outside of a factory/builder? Your design may need some better design patterns to help you split responsibilities.
  • Are your functions easy to test? Make your functions easy to test, they will fall apart.
  • Is it complex and just no land in sigth (1000 line monsters)? Do scrap refactoring - that is refactor and don't save it in the hope to get educated about the codes responsibilities.
Johannes
  • 336
0

Here are some clues:

  • If you are having trouble writing the comment explaining the purpose and usage of the function, it is too long.

  • If you are tempted to write a comment explaining the activity of a section of code in the function, then the function is too long.

  • If you are pasting code from another function, then they are both too long (extract that code as a separate function).

  • If you need a coding convention to separate class data members from local variables, then the function is too long, and the class has too many members.

  • If you need to take notes while reading a function, it is too long.

Having 'tonnes' of functions, each only one or two lines long, is not necessarily a bad thing. I found that those little functions were reused much more than I initially expected.

kevin cline
  • 33,670