일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 장애물인식
- 이펙티브자바
- 운영체제
- persistance context
- 논문리뷰
- 아두이노
- Database
- 논문
- Python
- 디자인패턴
- Hibernate
- 자바
- 알고리즘
- 네트워크
- JPA
- Java
- 영속성컨텍스트
- 배달로봇
- 포인트클라우드
- 프로그래머스
- 딥러닝
- 자율주행
- Jetson
- Spring Batch
- cartograhper
- MySQL
- DeepLearning
- 자료구조
- 자바ORM표준JPA프로그래밍
- 파이썬
- Today
- Total
제리 devlog
[이펙티브 자바] 문자열 연결은 느리니 주의하라 + 문자열 연결 방법 비교 본문
+ 연산으로 계산한 경우
10만개의 "abcd"를 붙였다.
public static void main(String[] args){
long startTime = System.currentTimeMillis();
String result = "";
for(int i=0; i<100000; i++){
result += "abcd";
}
long endTime = System.currentTimeMillis();
System.out.println("걸린 시간 : " + (float)(endTime-startTime)/1000 + "초");
}
문자열 연결 연산자로 문자열n개를 잇는 시간은 n^2에 비례한다. 문자열은 immutable해서 두 문자열을 연결할 경우 양쪽 내용을 모두 복사해야한다.
StringBuilder를 사용한 경우
10만개의 "abcd"를 붙였다.
public static void main(String[] args){
long startTime = System.currentTimeMillis();
StringBuilder builder = new StringBuilder(4 * 100000);
for(int i=0; i<100000; i++){
builder.append("abcd");
}
String result = builder.toString();
long endTime = System.currentTimeMillis();
System.out.println("걸린 시간 : " + (float)(endTime-startTime)/1000 + "초");
}
용량 설정을 입력 수와 달리하고 500만개의 "abcd"를 붙였다.
public static void main(String[] args){
..
StringBuilder builder = new StringBuilder(4 * 100000);
for(int i=0; i<5000000; i++){
builder.append("abcd");
}
..
}
용량 설정을 입력 수와 맞추고 500만개의 "abcd"를 붙였다.
public static void main(String[] args){
..
StringBuilder builder = new StringBuilder(4 * 5000000);
for(int i=0; i<5000000; i++){
builder.append("abcd");
}
..
}
append과정에서 확인하고 용량이 부족하면 용량을 입력받은 String의 길이만큼 더 추가한다. 매번 이 작업이 이뤄지기 때문에 초기 용량 값 설정이 속도에 영향을 준다.
concat을 사용한 경우
10만개의 "abcd"를 붙였다.
public static void main(String[] args){
..
String result = "";
for(int i=0; i<100000; i++){
result = result.concat("abcd");
}
..
}
concat과 StringBuilder의 차이점은 concat은 매번 새로운 String 객체를 만들고 StringBuilder는 append로 char array를 만들었다가 toString메서드 호출시 String객체를 만든다.
StringBuffer를 사용한 경우
10만개의 "abcd"를 붙였다.
public static void main(String[] args){
..
StringBuffer sb = new StringBuffer(4* 100000);
for(int i=0; i<100000; i++){
sb.append("abcd");
}
String result = sb.toString();
..
}
용량 설정을 입력 수와 달리하고 500만개의 "abcd"를 붙였다.
public static void main(String[] args){
..
StringBuffer sb = new StringBuffer(4* 100000);
for(int i=0; i<5000000; i++){
sb.append("abcd");
}
String result = sb.toString();
..
}
용량 설정을 입력 수 같게하고 500만개의 "abcd"를 붙였다.
public static void main(String[] args){
..
StringBuffer sb = new StringBuffer(4* 5000000);
for(int i=0; i<5000000; i++){
sb.append("abcd");
}
String result = sb.toString();
..
}
StringBuffer의 append도 타고가보면 StringBuilder와 같은 메서드를 사용한다.
비교 결과 : StringBuilder > StringBuffer > concat >> +연산
실제 벤치 마크를 비교해보자.
StringBuilder와 StringBuffer가 유사하고 그다음으로 concat과 +연산 순서였다.
StringBuilder와 StringBuffer중 어떤걸 써야하나?
둘다 append시 같은 메서드를 사용하고 있었다. 그렇다면 어떤 차이가 있을까?
둘의 차이는 synchronized에 있다. thread safe하게 보장하는지 아닌지가 다른 것이다.
synchronized키워드르 사용해서 동기화를 하게되면 block과 unblock을 처리하게 되는데 이런 처리로 인해 프로그램 성능이 저하될 수 있다.
단일 스레드 환경에서는 StringBuilder, 멀티 스레드 환경에서는 StringBuffer가 적합하다.
'Java' 카테고리의 다른 글
[이펙티브자바] 최적화는 신중히 하라 (0) | 2020.11.30 |
---|---|
[이펙티브 자바] 객체는 인터페이스를 사용해 참조하라 (0) | 2020.11.23 |
[이펙티브자바] finalizer와 cleaner 사용을 피하라 (0) | 2020.11.17 |
[이펙티브자바] 자원을 명시하지 말고 의존 객체 주입을 사용하라 (0) | 2020.11.05 |
[이펙티브자바] 인스턴스화를 막으려거든 private 생성자를 사용해라 + java static 개념 (0) | 2020.10.29 |