Performance bei der Benutzung von Format Strings

Tikonteroga

Erfahrenes Mitglied
Hallo,

ich habe es mir aus Gründen der Lesbarkeit angewöhnt beim Arbeiten mit Strings Methoden zu verwenden, die einen Format String verwenden (z. B. String.format() oder das printf von verschiedenen Klassen (PrintWriter, ...)).

Kostet mich dieser Stil sehr viel Performance ? Sollte ich doch den StringBuilder dafür verwenden ?

Gruß

Tikonteroga
 
Hallo,

ich habe mal versucht ein kleines Benchmark-Programm zu schreiben. Eine Variante in der ich einen StringBuilder verwendet habe und ein Beispiel in dem ich einen FormatString verwendet habe. Bei meinem Vergleich ist die Variante mit dem StringBuilder um über den Faktor 2 schneller. Getestet habe ich auf einem Core 2 Duo E8400, 4 GB Ram und einer Intel SSD mit 160 GB.

Man muss dabei jedoch beachten, dass ich die Variante mit dem StringBuilder optimiert habe, indem ich die Capacity optimal gewählt habe.

Code:
pubic static void formatString() throws IOException {
		long initialTime = System.currentTimeMillis();
		
		FileWriter fileWriter = new FileWriter(new File("format.txt"));
		BufferedWriter bufferedWriter = new BufferedWriter(fileWriter, 433);
		PrintWriter printWriter = new PrintWriter(bufferedWriter);
		
		for(int index = 0; index < Short.MAX_VALUE; index++) {
			
			printWriter
				.printf("Byte: %d, Float: %f, String: %s, Double: %f, Long: %d", 
						Byte.MAX_VALUE, Float.MAX_VALUE, "String", 
						Double.MAX_VALUE, Long.MAX_VALUE);
		}
		
		printWriter.close();
		
		long remainingTime = System.currentTimeMillis() - initialTime;
		
		System.out.printf("Execution Time of Format String Variant: %s ms\n", 
				remainingTime);
	}

Execution Time of Format String Variant: 1477 ms
Execution Time of Format String Variant: 1467 ms
Execution Time of Format String Variant: 1468 ms

Code:
public static void stringBuilder() throws IOException {
		long initialTime = System.currentTimeMillis();
		
		FileWriter fileWriter = new FileWriter(new File("builder.txt"));
		BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
		
		StringBuilder stringBuilder = new StringBuilder(433);
		
		for(int index = 0; index < Short.MAX_VALUE; index++) {
			
			stringBuilder.append("Byte: ");			//006 Characters 
			stringBuilder.append(Byte.MAX_VALUE);	//003 Characters
			stringBuilder.append(", Float: ");		//009 Characters
			stringBuilder.append(Float.MAX_VALUE);  //046 Characters
			stringBuilder.append(", String: ");		//010 Characters
			stringBuilder.append("String");			//006 Characters
			stringBuilder.append(", Double: ");		//010 Characters
			stringBuilder.append(Double.MAX_VALUE);	//316 Characters
			stringBuilder.append(", Long: ");		//008 Characters
			stringBuilder.append(Long.MAX_VALUE);   //019 Characters
			
			bufferedWriter.write(stringBuilder.toString());
			stringBuilder.setLength(0);
		}
		
		bufferedWriter.close();
		
		long remainingTime = System.currentTimeMillis() - initialTime;
		
		System.out.printf("Execution Time of String Builder variant: %s ms\n", 
				remainingTime);
	}

Execution Time of String Builder variant: 624 ms
Execution Time of String Builder variant: 624 ms
Execution Time of String Builder variant: 624 ms
 
Es kommt auf den Anwendungsfall an. Das generelle "Problem" ist, dass primitive Datentypen zuerst zu einem Object geboxt werden müssen, bevor sie rausgeschrieben werden kann. Das Suchen und Ersetzen braucht sicherlich auch noch Zeit ist aber imo vernachlässigbar.

Generell ist die Frage, was man damit machen will? Will man tausende Werte in einen String umwandeln? Dann ist sicher der manuelle Weg über StringBuilder besser.
Oder will man nur eine log-Ausgabe machen? Dann reicht String.format.


@Tikonteroga

Eine gute Idee, aber ich finde dein Beispiel nicht aussagekräftig.
1. benutzt du Dateien Ausgabe. Das variiert sehr stark, besonders durch OS spezifisches Caching.
2. Als Eingabe-Werte werden feste Werte benutzt und keine Variablen->boxing
2. Braucht die VM eine gewisse Zeit, bevor sie sich komplett initializiert hat.
 
Zuletzt bearbeitet:
Zurück