Michael HönnigMichael Hönnig
Viele Experten empfehlen, besser viele kurze Methoden zu programmieren als wenige lange Methoden. Dieselbe Regel kann auch aus anderen Empfehlungen abgeleitet werden. So führen z..B das Prinzip One level of abstraction und das Single Responsibility Principle zu kurzen Methoden. Und auch die Empfehlung, dass die im Quellcode verwendeten Bezeichner, also auch Methodennamen, ihr Subjekt ausreichend dokumentieren sollten, läuft auf kurze Methoden hinaus. Ein häufiges Gegenargument ist, die Performance sei aufgrund der vielen Funktionsaufrufe schlechter. Nun, auch hier gibt es wieder eine Empfehlung: Vorsicht vor Optimierungen - insbesondere dann, wenn Optimierungen den Quellcode schwerer lesbar, schwerer testbar oder schwerer änderbar machen, was fast immer der Fall ist. Robert C. Martin hat in seinem Buch Clean Code (deutsche Ausgabe im mitp Verlag, 2009) im Kapitel 2 das folgende (hier leicht angepasste) Programmbeispiel, einmal in einer Methode:
    private static String formatStatistics(char candidate, int count)  {
		String number;
		String verb;
		String pluralModifier;
		if ( count == 0 ) {
				number = "no";
				verb = "are";
				pluralModifier = "s";
		} else if ( count == 1 ) {
				number = "one";
				verb = "is";
				pluralModifier = "";
		} else {
			number = Integer.toString(count);
			verb = "are";
			pluralModifier = "s";
		}
		return String.format("There %s %s %s%s.", 
                        verb, number, candidate, pluralModifier);
	}
Und einmal aufgeteilt auf mehrere Methoden.
static class StatisticsFormatter {
	char candidate;
	int count;
	String number;
	String verb;
	String pluralModifier;

	public StatisticsFormatter(char candidate, int count) {
		this.candidate = candidate;
		this.count = count;
		createPluralDependentMessageParts(count);
	}

	private final void createPluralDependentMessageParts(int count) {
		if ( count == 0 ) {
			thereAreNoLetters();
		} else if ( count == 1 ) {
			thereIsOneLetter();
		} else {
			thereAreMultipleLetters();
		}
	}
	
	private final void thereAreNoLetters() {
		number = "no";
		verb = "are";
		pluralModifier = "s";
	}

	private final void thereIsOneLetter() {
		number = "one";
		verb = "is";
		pluralModifier = "";
	}

	private final void thereAreMultipleLetters() {
		number = Integer.toString(count);
		verb = "are";
		pluralModifier = "s";
	}

	public final String format() {
		return String.format("There %s %s %s%s.", 
                               verb, number, candidate, pluralModifier);
	}
}
Anhand dieses Beispiels habe ich nun getestet, wie groß der Performance-Unterschied mit Java 1.6.14 ist. Das Ergebnis ist erstaunlich. Für 10.400.000 Durchläufe (4000 mal 26 Buchstaben als jeweils mit Count 0-99) mit verschiedenen candidata/count-Kombinationen, aber in beiden Fällen denselben, kommt die 1-Methoden Variante auf 277,893s, und die mehr-Methoden-Variante auf 278,449s, also ein Unterschied in der Größenordnung eines Bruchteil eines Prozents. Weniger Schleifendurchläufe führten außerdem zu Messwerten, bei denen mal die 1-Methoden-Variante und mal die mehr-Methoden-Variante schneller war. Fakt ist jedenfalls, die HotSpot-VM leistet gute Arbeit und durch Vermeidung von Funktionsaufrufen, die Performance optimieren zu wollen, ist allenfalls reine Illusion.