2011-08-03 4 views
4

자바에서 String, StringBuilder 및 StringBuffer로 작업했습니다.
효율성의 관점에서 생각하는 동안이 질문을 생각했습니다.문자열 연결에서 "+"사용이 효율성에 영향을 줍니까?

문자열 연결에서 "+"사용이 효율성에 영향을 줍니까?

+2

나는 이것이 여기에 많이 논의 된 것 같아요? – Jacob

+0

그래, 두 개 이상의 문자열을 연결하는 경우 stringbuilder를 사용해야한다는 규칙이 있습니다 ... 아이디어/미리 응답 시간이있는 경우 (1) 질문에 추가 정보로 넣거나 (b) 이미 답을 알고있는 질문을하지 마십시오. – Patrick87

답변

5

예, 그렇지만 대부분 시간 문제가되지는 않습니다.

문자열 상수에 '+'를 사용하면 컴파일러가 연결을 수행 할 때 가장 효율적입니다.

두 개의 문자열을 조인 할 경우 concat 메서드가 StringBuilder를 사용하지 않으므로 가장 효율적입니다.

이전 버전과의 호환성을 제외하고는 StringBuffer를 사용하지 않는 것이 좋습니다. StringBuilder 또는 StringWriter를 사용하는 것이 더 좋습니다. 그러나, 여전히 JDK에서의 StringBuilder보다 명시 적으로 더 자주 사용됩니다 컴파일러/JIT 컴파일러가 자동으로 최적화하기 때문에 P

StringBuffer is dead, long live StringBuffer

+0

작은 연결의 경우 "너무 작음". 그러나, 나는 많은 연결 (파서/필터)을 가진 클래스를 다루는 경험이 있었는데, 단순히 연결에서 버퍼로 변경하면 (매우 느린) 실행 시간이 반으로 줄어 듭니다. Microbenchmarks는 또한 여분의 중간 문자열 객체를 모두 추가하는 데 따른 가비지 콜렉션 비용을 표시하지 않지만 응용 프로그램 수명 동안 상각됩니다. –

+0

내 응용 프로그램에서 스레드 로컬 ByteBuffer를 사용하고 개체를 만들지 않는 메서드를 사용하여 직접 읽기/쓰기를 수행합니다. 유스 케이스의 99 %는 꽤 극단적인데, 몇 초가 소요될 수 있습니다.;) –

1

네의 비트,하지만 JLS에서 여전히 NO

, 15.18.1.2

최적화 문자열의 병합

구현은 변환을 수행하도록 선택할 수 있고 연결 을 생성 한 후이를 버리는 것을 피하려면 한 단계에서 문자열 개체를 사용합니다. 반복되는 문자열 연결의 성능을 높이려면 Java 컴파일러에서 StringBuffer 클래스 또는 비슷한 기술을 사용하여 식의 평가에 의해 생성 된 중간 문자열 개체 의 수를 줄이십시오.

기본 유형의 경우 구현은 기본 유형에서 문자열로 직접 변환하여 래퍼 객체 작성을 최적화 할 수도 있습니다.

4

단일 문에 합치하는 경우, 그것은 중요하지 않습니다 StringBuilder을 사용합니다. 루프에서 String의 많은을 연결하는 경우

그래서 "a"+b+"c"

는 크게 프로그램을 빠르게하므로 확실히 명시 적으로 StringBuilder를 사용, 그러나 (new StringBuilder("a").append(b).append("c")).toString()

에 최적화됩니다. 문자열은 불변이므로

String a = ""; 

for(int i = 0; i < 1000000; i++) 
    a += i; 

문자열을 연결하여 문자열 생성 원인

StringBuilder sb = new StringBuilder(); 

for(int i = 0; i < 1000000; i++) 
    sb.append(i); 

String a = sb.toString(); 
-1

로 변경되어야한다. ie .. "A"+ "B"+ "C"는 "AB", "ABC"의 생성을 유발합니다.다중 연결을 수행하는 경우 StringBuilder를 사용하는 것이 더 효율적입니다 (동기화 비용이있는 구형이지만 API가 동일한 StringBuffer가 아님)

한 줄 연결이 있으면 컴파일러에서이 작업을 수행합니다 가능하다면 - 즉, "A"+ "B"+ "C"를 컴파일하면 디 컴파일하면 새로운 StringBuilder ("A")와 같은 것을 볼 수 있습니다 : append ("B"). append ("C"). toString(). 그러나 컴파일러는 여러 줄에 걸쳐 여러 줄의 concat을 최적화 할 수 없습니다. 즉, 여러 줄을 연결하는 경우 추가 StringBuilder 만들기를 포함하여 각 줄마다 위와 비슷한 내용을 보게됩니다. 수동으로하는 것이 더 좋습니다.

간단한 예제를 작성하고 디 컴파일하여 직접 확인할 수 있습니다. 당신의 예에서

+0

이 틀리면 "A"+ "B"+ "C"라고 쓰면 중간 문자열을 얻지 못합니다. – eckes

1

:

" Does +" + " use in String concatenation affect efficiency? " 

우리가 컴파일러에 의해 대체 될 수 있습니다 리터럴 문자열로, 그래서이 빠르고, StringBuffer와/APPEND/toString보다됩니다.

그러나 무엇보다 효율적/더 빠릅니까? 코드 실행? 코드 작성? 코드 읽기?

"Foo = " + foo; 

을 읽는 것은 매우 쉽기 때문에

, 나는 백만 번 반복되지 않는 한, 추천, 또는 것 "S + = (S2);" hundret 번 반복.

특히

,

System.out.println ("Player " + n + " scores " + player[n].score); 

그냥 문자열의 매우 많은 양의, 또는 반복적으로 많은 양의 높은 성능이 필요하거나 연결하여 응용 프로그램에서 그것을 피할 훨씬 더 읽을 수

System.out.println (new StringBuffer ("Player ").append ((Integer.valueOf (n)).toString().append (" scores ").append (... 

보다.

-1

'+'를 여러 번 사용하면 일부는 확장됩니다. Coz String a + String b를 수행하면 내부적으로 StringBuffer 객체가 만들어지고 StringBuffer의 append()를 사용합니다. 그래서 당신이 '+'할 때마다 새로운 임시 StringBuffer 객체는 "a"로 초기화되고 "b"가 추가 된 다음 생성되어 문자열 객체로 변환됩니다.

여러 연결이 필요하면 StringBuffer (스레드 세이프)/StringBuilder (스레드 세이프가 아닌) 객체를 만들고 계속 추가해야하므로 StringBuffer 객체가 반복해서 생성되는 것을 피할 수 있습니다.

+0

"여러"올바른 경우에만 여러 문에서 문자열을 확장합니다. +가있는 단일 명령문은 단일 stringbuilder만큼 효율적이지만 읽을 때 훨씬 좋습니다 (컴파일러가 초기 크기를 더 잘 최적화 할 수 있음). – eckes

+0

두 번째 단락에서이 문제를 해결할 것으로 확신합니다. –

관련 문제