tifyty

pure Java, what else ?

StringBuilder és String konkatenáció

Vegyünk egy egyszerű programot:

public class StringAdd {
	public static String stringAdd(String a, String b) {
		return a + b;
	}
	public static void main(String[] args) {
		System.out.println(stringAdd("a", "b"));
	}
}

és egy másikat:

public class StringAddUsingStringBuilder {
	public static String stringAdd(String a, String b) {
		return new StringBuilder().append(a).append(b).toString();
	}
	public static void main(String[] args) {
		System.out.println(stringAdd("a", "b"));
	}
}

Dilemma: melyik a jobb. Melyik generál hatékonyabb kódot? Persze tudom, egy ilyen egyszerű példa esetében ez irreleváns, de adott esetben valami hasonló előfordulhat egy nagyobb kódban is, egy erősen terhelt ciklus közepén. Az biztos így ránézésre is, hogy az első megoldás sokkkkaallll olvashatóbb.

Ha elég sokat gondolkodtunk már azon, hogy vajon melyik a hatékonyabb, akkor nézzük meg a bájtkódot (mostanában rettentően beleszerettem ebbe a bájtkódba, ifjúságomat juttatja eszembe, amikor még számított, hogy egy XOR A egy bájttal rövideb, mint a LD A,0).

Az első programból generált bájtkód releváns része:

  public static java.lang.String stringAdd(java.lang.String, java.lang.String);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=2
         0: new           #2                  // class java/lang/StringBuilder
         3: dup
         4: invokespecial #3                  // Method java/lang/StringBuilder."<init>":()V
         7: aload_0
         8: invokevirtual #4                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        11: aload_1
        12: invokevirtual #4                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        15: invokevirtual #5                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        18: areturn

A második programból generált kód:

  public static java.lang.String stringAdd(java.lang.String, java.lang.String);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=2
         0: new           #2                  // class java/lang/StringBuilder
         3: dup
         4: invokespecial #3                  // Method java/lang/StringBuilder."<init>":()V
         7: aload_0
         8: invokevirtual #4                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        11: aload_1
        12: invokevirtual #4                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        15: invokevirtual #5                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        18: areturn

Akkor most ebből tessék levonni a következtetést.

$ java -version
java version "1.7.0_07"
Java(TM) SE Runtime Environment (build 1.7.0_07-b10)
Java HotSpot(TM) 64-Bit Server VM (build 23.3-b01, mixed mode)

Azért, mielőtt még valaki kidobná a forráskódjából az összes StringBuilder-t: nem mindent konvertál át a javac ilyen okosan! Ha egy ciklusban fűzöm össze egy String tömb elemeit, akkor minden egyes ciklus végén visszaalakítja az eredményt String-é, és minden cikluslefutás előtt új StringBuilder-t épít!

4 responses to “StringBuilder és String konkatenáció

  1. Gábor Lipták december 14, 2012 10:53 du.

    A helyes válasz, hogy az első hatékonyabb, mert kevesebbet kell írni. Amúgy semmi különbség persze 🙂

  2. tamasrev december 19, 2012 2:55 du.

    Azt hallottam – elkéne ide egy normális hivatkozás – hogy java5-től fölfelé a fordítási folyamat közben a String konkatenáció kicserélődik StringBuilder-ré. Akkor viszont az első jobb, mert olvashatóbb.

  3. anoni-mouse december 24, 2012 11:37 de.

    Azt hiszem erről szól ez a bejegyzés is: http://wiki.javaforum.hu/pages/viewpage.action?pageId=23560282
    De jó, hogy megemlíted!

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s

%d blogger ezt kedveli: