2013-02-08 16 views
8

Wariant 1:Concat a integer to a String - użyj literału podstawowego lub pierwotnego z wydajności i punktu widzenia pamięci?

String newStr = someStr + 3 + "]"; 

Opcja 2:

String newStr = someStr + "3" + "]"; 

Która opcja jest lepsza jeśli chodzi o wydajność, pamięci i ogólnej praktyce? Jakie są niektóre zalecane narzędzia/sposoby, których mogę użyć do pomiaru użycia pamięci mojego kodu i jego wydajności (poza pomiarem czasu rozpoczęcia i zakończenia oraz obliczenia różnicy)

+0

Zarówno nie robi żadnej różnicy. – Smit

+0

@Smit: Kompilator użyje 'StringBuilder' do konkatenacji ciągów znaków – jlordo

+0

@Smit: użycie StringBuilder doprowadziłoby do tego samego kodu bajtowego, co kod w pytaniu, lub gorzej. –

Odpowiedz

6

Nie będzie żadnej zauważalnej różnicy między obydwoma . Użyj tego, co uważasz za najbardziej logiczne i czytelne. użyłbym

String newStr = someStr + "3]"; 
3

Polecam Jprofiler jako wielki aplikacja Java narzędzie do profilowania, które pomogły mi znaleźć wiele problemów z pamięcią.

Nie sądzę, że opcje 1 i 2 mają dużą różnicę pod względem wykorzystania pamięci, szczególnie jeśli jest to aplikacja komputerowa.

+0

Dzięki za sugestię narzędzia! – user1739658

+0

Nie ma problemu! Proszę przyjąć najbardziej użyteczną odpowiedź ;-) – Simon

10

Pierwszy staną:

StringBuilder sb = new StringBuilder (String.valueOf (someStr)); 
sb.append (3); 
sb.append ("]"); 
String newStr = sb.toString(); 

drugi staną:

StringBuilder sb = new StringBuilder (String.valueOf (someStr)); 
sb.append ("3"); 
sb.append ("]"); 
String newStr = sb.toString(); 

Oto demontaż:

public String foo (String someStr) 
{ 
    String newStr = someStr + 3 + "]"; 
    return newStr; 
} 

public String bar (String someStr) 
{ 
    String newStr = someStr + "3" + "]"; 
    return newStr; 
} 

public java.lang.String foo(java.lang.String); 
Code: 
    0: new   #16     // class java/lang/StringBuilder 
    3: dup 
    4: aload_1 
    5: invokestatic #18     // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 
    8: invokespecial #24     // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 
    11: iconst_3 
    12: invokevirtual #27     // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 
    15: ldc   #31     // String ] 
    17: invokevirtual #33     // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    20: invokevirtual #36     // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    23: astore_2 
    24: aload_2 
    25: areturn 

public java.lang.String bar(java.lang.String); 
Code: 
    0: new   #16     // class java/lang/StringBuilder 
    3: dup 
    4: aload_1 
    5: invokestatic #18     // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 
    8: invokespecial #24     // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 
    11: ldc   #44     // String 3 
    13: invokevirtual #33     // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    16: ldc   #31     // String ] 
    18: invokevirtual #33     // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    21: invokevirtual #36     // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    24: astore_2 
    25: aload_2 
    26: areturn 
+3

Pierwsza z nich doda "3" (w polu Integer 3), a następnie dopisze ']'. Drugi dołącza '3]' –

+0

+1. Nie wiem dlaczego, ale moje oczy widziały stałą w drugim przypadku, ale nie w pierwszym. –

+0

Ups. Steve Kuo ma rację.'String s =" hello "+ 3 +"] "' tworzy pojedynczy ciąg '" hello3] "' chociaż. Dziwne, że kompilator nie może zoptymalizować tego przypadku. +1 wciąż, bo czegoś się nauczyłem. –

1

Zakładając, że someString jest stała, obie są wyrażenia stałe i zostaną ocenione podczas kompilacji. Powstaną identyczne pliki klas i zachowanie środowiska wykonawczego.

Źródło: Java Language Specification pisze:

kompilacji czasu stała ekspresja jest wyrazem oznaczającym wartość prymitywnego typu lub ciąg znaków, który nie kończy się nagle i składa się tylko przy użyciu następujących:

  • literały prymitywnego rodzaju i literałach typu łańcuchowego (§3.10.1, §3.10.2, §3.10.3, §3.10.4, §3.10.5)

  • dodatek ope rators + i - (§15.18)

  • ...

kompilacji stałe wyrażenia typu String są zawsze "internowany", tak aby dzielić wyjątkowe przypadki, stosując metodę String.intern.

Jeśli someString nie jest stałą, większość nowoczesnych kompilatory użyje StringBuilder, która jest wyraźnie permitted przez języka Java Specification:

Wynikiem ciąg konkatenacji jest odniesieniem do obiektu String że jest połączeniem dwóch ciągów operacji. Znaki lewego operandu poprzedzają znaki prawostronnego operandu w nowo utworzonym łańcuchu.

Obiekt String jest nowo utworzony (§ 12.5), chyba że wyrażenie jest wyrażeniem stałym w czasie kompilacji (§15.28).

Implementacja może wybrać konwersję i konkatenację w jednym kroku, aby uniknąć tworzenia, a następnie odrzucania pośredniego obiektu String. Aby zwiększyć wydajność powtarzanego łączenia ciągów, kompilator Java może używać klasy StringBuffer lub podobnej techniki w celu zmniejszenia liczby pośrednich obiektów String, które są tworzone przez ocenę wyrażenia.

Dla typów pierwotnych implementacja może również optymalizować tworzenie obiektu opakowania poprzez konwersję bezpośrednio z typu pierwotnego na ciąg znaków.

+0

Jest to bardzo pomocne. Dziękuję Ci bardzo! – user1739658

0

Ilekroć łączymy ciąg, na każdej konkatenacji tworzona jest nowa kopia ciągu, a oba ciągi są kopiowane po jednym znaku na raz. Powoduje to złożoność czasową O (n) (McDowell).

Jeśli chcesz poprawić wydajność, użyj

StringBuilder 

jeden z jej konstruktorów ma następującą składnię: (. Zmienny sekwencję znaków Pamiętaj ciągi są immmutable)

public StringBuilder(int size); //Contains no character. Initial capacity of 'size'. 

StringBuilder pomaga rozwiązać ten problem problem po prostu tworząc zmienną tablicę wszystkich łańcuchów. kopiowanie ich na ciąg tylko wtedy, gdy jest to konieczne (McDowell).

StringBuilder str = new StringBuilder(0); 
str.append(someStr); 
str.append(3); 
str.append("]"); 

referencyjny:

McDowell, Gayle Laakmann. Cracking The Coding Interview, wydanie szóste. Wydrukować.

"Stringbuilder (platforma Java SE 8)". Docs.oracle.com. N.p., 2016. Web. 4 czerwca 2016.