Thursday, February 25, 2010

Ginormous Methods (-XX:-DontWriteHugeMethods)

You know what I like to see when I open up a class? Not much. That is, I like my classes with Single Responsibility, and I like their methods short and to the point. If there are lots of different paths, maybe polymorphism should pay a visit.

But, I'm not pharisaic in this regard. I mean, if some of the methods ramble on a bit, well, that's just what happens sometimes. So, I'll cut some slack on rather long methods.

That's not what I'm talking about today. I'm not talking about methods that scroll off the screen. Those are big methods. I'm talking about methods that go on for so long, if you didn't have a nice IDE, you would have long forgotten what the name of the method is, or if you're still in it! I'm talking about 1000+ line long methods. Oh yeah.

So, besides the fact that maintainers of this code will likely want to throw themselves off of something tall, what is the problem? Let's back up a bit. First, methods of this length are a real problem. Specifically, when some poor soul goes to add some logic to this method, there are often so many variables on the stack, they don't even know if the data they need is available. They'll probably just go get it again. And, forget about testing this thing. Odds are the number of side-effects is about as long as the method, and so even if you could set up all the hundreds of fixtures, you'd need hundreds of asserts to insure the method did all of the things it does.

But, guess what... there's another problem, and it doesn't involve developers. It turns out that the JVM doesn't care for ginormous methods either. Basically, once your method exceeds 8kB of bytecode, the JVM sort of hangs it up, and says, forget this, I'm not going to JIT this method (OK, you can ask really nicely with -XX:-DontCompileHugeMethods, but really, that's not the path you want to take). Even worse, I've seen situations in deployed environments where the JVM will crash, because it's just such a tangly mess of oop maps and confusion.

So, if you ever find yourself in a situation where you're arguing over how bad a method needs to be refactored, and the opposition isn't responding to squishy things like maintainability, testability, developer morale, sanity, etc., then now you can pull out performance as another reason. You might just surprise them enough to get it changed.