티스토리 뷰
728x90
반응형
문자열 연결은 느리니 주의하라
- 문자열 연결 연산자(+)는 여러 문자열을 하나로 합쳐주는 편리한 수단입니다. 하지만 여러 문자열을 많이 합치게 되는 경우 성능 저하의 문제가 발생할 수 있습니다.
- 문자열 연결 연산자(+)로 문자열 n개를 잇는 시간은 n2에 비례합니다.
💡연결 연산자를 사용하는 경우
public class Example {
public static void main(String[] args) {
String str = "";
for (int i = 0; i < 100000; i++) {
str += i;
}
System.out.println(str); // 16 sec, 948ms 소요
}
}
💡StringBuilder를 사용하는 경우
- 상당히 빨라진것을 알 수 있습니다.
public class Example {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100000; i++) {
sb.append(i);
}
System.out.println(sb.toString()); // 2 sec, 803ms 소요
}
}
💡String, StringBuffer, StringBuilder
- String과 StringBuffer는 자바 1.0의 등장과 함께 나왔습니다.
- StringBuilder는 자바 1.5에서 나왔습니다.
- String의 concat연산은 + 기호를 사용하여 concatination을 수행합니다.
- StringBuffer와 StringBuilder는 AbstractStringBuilder를 사용하고 있으며, 결국 같은 append 메서드를 사용합니다.
💡StringBuffer, StringBuilder의 차이
- StringBuffer의 append 메서드에는 syncronized 키워드가 있어서 thread-safe합니다. 하지만 StringBuilder의 append 메서드에는 해당 키워드가 없어 thread-safe하지 않습니다.
// StringBuffer
@Override
@HotSpotIntrinsicCandidate
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
// StringBuilder
@Override
@HotSpotIntrinsicCandidate
public StringBuilder append(String str) {
super.append(str);
return this;
}
- 멀티 쓰레드 환경에서는 StringBuffer를 사용하는것이 안전합니다.
- 단일 thread라면 StringBuilder를 사용하는것이 StringBuffer를 사용하는 것 보다 성능이 좋습니다.
💡String의 + 연산이 느린 이유
- String은 불변 클래스이기 때문에 String + String을 하기 위해서는 String 내의 char[] 또는 byte[]을 복사합니다.
- 2개의 array의 length를 더한 값으로 새로운 배열을 만들게 됩니다. 그리고 array에 기존의 값을 채워넣고 new String으로 새로운 String 객체를 생성하게 됩니다. 이렇게 + 연산이 일어날 때마다 새로운 객체가 생성되니 힙 영역에서 String 객체가 많아지면 GC가 String 객체를 수거하기 시작하는데 GC동작시 stop the word라는 행위가 일어나게 됩니다.(JVM의 작동이 일시적으로 멈춥니다.)
이러한 행위가 계속 반복되면 결국 느려질 수 밖에 없습니다.
💡String의 + 연산자의 발전
- Java String 연산에 대한 성능 최적화를 다방면으로 생각하고 Java 9부터는 String의 내부 배열을 char[] -> byte[]로 변경하여 성능을 더 향상 시켰습니다.
- java 1.5 버전부터 String + String 연산에 대해 컴파일 타임에 StringBuilder를 사용하도록 코드를 변경합니다. 하지만 JDK가 항상 자동으로 바꿔준다는 보장이 없기 때문에 해당 연산에 대해서는 안전하게 StringBuilder를 사용하는게 좋습니다.
참고 자료)
728x90
반응형
'스터디 > 이펙티브 자바' 카테고리의 다른 글
이펙티브 자바 - Item66. 네이티브 메서드는 신중히 사용하라 (0) | 2022.08.16 |
---|---|
이펙티브 자바 - Item64. 객체는 인터페이스를 사용해 참조하라 (0) | 2022.08.16 |
이펙티브 자바 - Item62. 다른 타입이 적절하다면 문자열 사용을 피하라 (0) | 2022.08.13 |
이펙티브 자바 - Item61. 박싱된 기본 타입보다는 기본 타입을 사용하라 (0) | 2022.08.11 |
이펙티브 자바 - Item58. 전통적인 for문보다는 for-each문을 사용하라 (0) | 2022.08.09 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- redis sorted set으로 대기열 구현
- java ThreadLocal
- spring boot excel download oom
- 자바 백엔드 개발자 추천 도서
- redis 대기열 구현
- pipe and filter architecture
- @ControllerAdvice
- 레이어드 아키텍처란
- 람다 표현식
- spring boot poi excel download
- spring boot excel download paging
- spring boot redisson 분산락 구현
- java userThread와 DaemonThread
- spring boot 엑셀 다운로드
- spring boot redisson destributed lock
- spring boot redis 대기열 구현
- transactional outbox pattern
- JDK Dynamic Proxy와 CGLIB의 차이
- redis sorted set
- pipeline architecture
- service based architecture
- 트랜잭셔널 아웃박스 패턴 스프링부트
- 공간 기반 아키텍처
- 서비스 기반 아키텍처
- 트랜잭셔널 아웃박스 패턴 스프링 부트 예제
- transactional outbox pattern spring boot
- polling publisher spring boot
- space based architecture
- microkernel architecture
- spring boot redisson sorted set
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함