문자열 연결: concat() 대 &&&;+&&; 연산자
문자열 a와 b를 가정합니다:
a += b
a = a.concat(b)
내부적으로는 같은 것일까요?
다음은 참조용으로 디컴파일된 컨캣입니다. '+' 연산자도 디컴파일하여 그 기능을 확인할 수 있으면 좋겠습니다.
public String concat(String s) {
int i = s.length();
if (i == 0) {
return this;
}
else {
char ac[] = new char[count + i];
getChars(0, count, ac, 0);
s.getChars(0, i, ac, count);
return new String(0, count + i, ac);
}
}
475
11
아니, 꼭 그런 것만은 아닙니다.
첫째, there& # 39 의 근소한 차이로 시맨틱스를. 만약 'a' 는 'null', 'a' a+ '하지만' 다음 '앨콩카트 던지는 누얼포인터렉세페시옹 (b) = b' 는 원래 값인 것처럼 'a' 치료 'null'. 또 '만' 방법을 사용할 수 있는 동안 concat () '+' 는 'String' 값을 자동으로 연산자입니다 변환하십시오 문자열으로 인수 (toString () '' 방법을 사용하여 객체에는). 따라서 'concat ()' 이 어떤 방식이 더 엄격한 받아들입니다.
'= a + b 클래스에 여바바 후드 아래에 쓰기 위해 간단한.'
이제 자바프 - 'c' 로 분해 (Sun JDK 에 포함). 다음과 같은 열거합니다 볼 수 있습니다.
따라서 '= a + b' 는 같습니다
Concat '방법' 이 더 빠를 것이다. 그러나 이 방법은 더욱 문장열 스트라이베이더 '승' 최소한 성능 면에서.
'소스 코드' 와 '문자열이어야 스트라이베이더' (및 그 패키지 pbs. (base class) 를 사용할 수 있는 세르히오치프 of the sun 에서 jdk. 보시다시피 틀렸다니까 구축에 챨 어레이입니다 (크기조정 필요한 경우) 를 만들 때 던진 후 거두어 최종 'String'. 실제 메모리 할당은 의외로 빨리 찾아온다.
[니야즈][1]가 맞지만, 특수 + 연산자는 Java 컴파일러에 의해 더 효율적인 것으로 변환될 수 있다는 점도 주목할 가치가 있습니다. Java에는 스레드에 안전하지 않고 변경 가능한 문자열을 나타내는 StringBuilder 클래스가 있습니다. 여러 문자열 연결을 수행할 때 Java 컴파일러는 다음과 같이 자동으로 변환합니다.
를
로 변환하는 것이 큰 문자열의 경우 훨씬 더 효율적입니다. 제가 알기로는 컨캣 메서드를 사용할 때는 이런 일이 발생하지 않습니다.
그러나 빈 문자열을 기존 문자열에 연결할 때는 concat 메서드가 더 효율적입니다. 이 경우 JVM은 새 String 객체를 생성할 필요가 없으며 기존 객체를 반환하기만 하면 됩니다. 이를 확인하려면
내가 대신 다음 루프 뿐만 아니라 비슷한 실행했음 @marcio 테스트입니다.
내가 던진 스트라이버일드리아펜드 () '에서', 딱 좋은 주옵니다 잘 알려져 있다. 각 시험은 각 10 배, 연파란색은 실행하십시오 100k 담당자 실행하십시오. 결과가 나타납니다.
39, 내가 haven& 디 컴파일 또는 내부 정보를 볼 수 없는 클래스 a + b '투데이' 의심이 통해 이를 실행하십시오 프로필러 않습니다만, 대부분의 시간 동안 스트라이베이더 의 새로운 개체를 만드는 '=' 다음 '다시' 문자열 변환.
다음은 가장 대답 (2008년). 그 시간에 따라 변하는 것을 보입니다. 내 주위에 있는 것을 알 수 있는 '+' 는 Java 최신값 벤치마크 브라운아저씨의 제마흐 2 배나 빠른 속도로 concat '8'.
내 벤치마트:
결과:
톰 올바른지 + 연산자 있는 것이 무엇인지 정확히 설명하는 않습니다. '임시' 을 (를) '및 마감, 부품, 첨부됩니다 e-lab 은 스트라이베이더 toString ()'.
그러나 지금까지 모든 답을 효과가 하스팟 런타임용으로 개발하십시오 최적화 외면당하고 있다. 특히 이러한 임시 작업은 보다 효율적인 기계어 실행 시 일반 패턴과 대체되었는지 평가받고 있다.
@marcio: # 39, ve you& 만든 마이크로 벤치마트. # 39 의 현대적 JVM& 이 올바르지 프로필링하려면 운행에서어떠한 코드.
그 이유는 런타임 최적화 문제는 이러한 많은 차이가 있다 하더라도 한 번 더 하스팟 객체 생성 등 코드 - - 완전히 다른 것입니다. 확실하게 알 수 있는 유일한 방법은,,) 는 < 프로필링 코드에 i> situ< /i>.
마지막으로, 이 모든 방법을 실제로 매우 빠르다. 이렇게 될 경우 아직 최적화합니다. 코드가 있을 경우 그 문자열을 연결합니다 많이 방법은 아마도 알고리즘을 선택할 수 있는 최대 속도 아무런 상관이 없고 대신 you& # 39, re 연산자를 사용하여!
몇 가지 간단한 테스트를 어때? 사용되는 코드는 아래와 같습니다.
여러 차례 테스트되었습니다. Concat () '이' 가 버전 엑서큐션 반단면 시간이 있는 것으로 나타났다.
그 때문에 항상 새로운 방법을 concat () '이 나를 놀라게 했다' 는 문자열 (String (결과) ',' new it 가 " ". # 39 의 it& 것은 널리 알려진:
왜 wasn& # 39 에서 작성, 컴파일러, a + b" 구체화하십시오 최적화합니다 " 수 없다. 그 결과 알고 항상 동일한 코드를 문자열? 피할 수 있다는 점에서 새로운 구체화하십시오 계시노라
39 위에 기술서임을 don& 경우, t believe the test for your self.
기본적으로 두 가지 중요한 차이점을 + '와' concat 메서드입니다.
문자열 s = 10 + " Hello";;
이 경우 출력입니다 10Hello 합니다.
문자열 s = " I";; 구체화하십시오 s1 (am" ";) = s.콩카트 이콩카트 이콩카트 (boy" ";), (good" ";) 시스템지우트리프린틀린 (s1).
위의 경우 두 문장열 제공하기 위해 필수.
문자열 s = " I";; 구체화하십시오 s1 (am" ";) = s.콩카트 이콩카트 이콩카트 (boy" ";), (good" ";) 시스템지우트리프린틀린 (s1).
이 경우 총 7 명) 에 작성된 객체에는 풀마다 다음과 같습니다.
난 키워봤지 좋은 보이 Iam 야마구드 리엄 굿보이
지금 난 것 같은 문장열 콩카티나티 통해 작동자 +
S = " +" am" +";;;;; I" 문자열이어야 good" boy" +";; 시스템지우트리프린틀린 (s).
위의 경우 총 5 만 작성된 객체에는 있다.
실제로 그런 유지보수합니다 스트라이버퍼 를 통해 하나님이 콩카티나티 + 동일한 작업을 수행할 수 있는 것처럼 문장열 연산자입니다 클래스용 inet6.0 -
스트라이버퍼 sb = new 스트라이버퍼 (I" ";). 스발라펜드 (am" ";). 스발라펜드 (good" ";). 스발라펜드 (boy" ";). 시스템지우트리프린틀린 (sb).
이런 식으로 불과 5 객체에는 생깁니다.
그래서 보세요들 그것은꿈의 기본 차이점 및 + concat 메서드입니다. 경험하십시오:)
생각해서라도 정의를 & # 39 +& 완성도, 내가 하고 싶은 것을 추가 # 39;; 연산자입니다 [JLS SE8 15.18.1] [1] 에서 볼 수 있다.
>. 만약 오직 하나의 피연산자를 표현식에서는 형식은 구체화하십시오 관심용 구체화하십시오 >. 변환 (& # 167. 5.1.11) 을 수행한 다른 피연산자 만들기 위해 >. 구체화하십시오 런타임에. >. >. 그 결과 연결 문자열을 string 객체에 대한 참조입니다 >. 즉 연결은 두 피연산자를 써줬지 문자 >. 이 문자는 오른쪽 왼쪽 피연산자 앞장서니까요 있다. >. 피연산자) 에 새로 만들어진 구체화하십시오. >. >. String 객체가 새로 만든 (& # 167, 12.5) 는 한 표현식에서는 >. 상수입니다 표현식에서는 (& # 167, 15.28).
그 다음 구축현 대한 JLS 밝혔습니다.
>. 변환 및 연결 실행하십시오 구현 선택할 수 있습니다. >. 한 번에 그리곤요 만들지 않도록 중간 취소 >. String 객체에. 연속된 문자열이어야 성능을 향상시키는 >. 연결, 자바 컴파일러는 클래스 또는 스트라이버퍼 사용할 수 있습니다. >. 이와 유사한 방법을 중간 구체화하십시오 개체 수를 줄일 수 있습니다. >. 평가를 통해 만들어진 충족되었으며 expression. >. >. 더 프리미티브 유형, 구축할 수 있는 빼냅니다 최적화합니다 수도 있습니다. >. 래퍼 (wrapper) 에서 직접 객체 생성 변환하여 프리미티브 >. 맞추기바인딩 string. 유형
그래서 & # 39 를 볼 때, 자바 컴파일러는 클래스 또는 이와 비슷한 방법을 사용할 수 있습니다, 다른 컴파일러에도 스트라이버퍼 reduce& # 39, 다른 바이트 코드 생산할 수 있다.
[1]: http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html # jls-15.18.1
연산자**는 문자열과 문자열, 문자, 정수, 이중 또는 부동 소수점 데이터 유형 값 사이에서 작동할 수 있습니다. 연결하기 전에 값을 해당 문자열 표현으로 변환하기만 하면 됩니다.
연결 연산자**는 문자열에 대해서만 사용할 수 있습니다. 데이터 유형 호환성을 검사하고 일치하지 않으면 오류를 발생시킵니다.
이 점을 제외하면 제공한 코드도 동일한 작업을 수행합니다.
그렇지 않다고 생각합니다.
a.concat(b)
는 문자열로 구현되며 초기 자바 머신 이후 구현이 크게 변경되지 않았다고 생각합니다. 연산
+구현은 자바 버전과 컴파일러에 따라 다릅니다. 현재
+는 가능한 한 빠른 연산을 위해 [
StringBuffer][1]를 사용하여 구현됩니다. 향후에는 변경될 수도 있습니다. 이전 버전의 Java에서는 문자열에 대한
+` 연산이 중간 결과를 생성하기 때문에 훨씬 더 느렸습니다.나는
+=
가+
를 사용하여 구현되고 비슷하게 최적화되었다고 생각합니다.S # 39 를 사용할 때 속도를 줄일 수 있지만, +, concat 사용할 때, 길이 캐시-코어 string& 속도는 더욱 안정적인, 그리고 최고의 옵션은 스트라이베이더 클래스를 사용하여 작업을 하기 위해서는 안정적인 속도용 디스크입니다. diskid iqn.
뭐 이유를 이해할 수 있다. 그러나 완전히 만들기 위한 최선의 방법을 사용하고 있고, 속도는 이보다 긴 문장열 스트라이베이더 덮어쓰기/추가 () () 와 용납될 수 없다.