기본 콘텐츠로 건너뛰기

String, StringBuffer, StringBuilder is Difference


1. String
1-1. 특징
- String 객체는 immutable 이다. , 한번 생성되면 String 객체가 변할 없다.
- 문자열, 숫자, char 등을 concat 할때는 StringBuffer, StringBuilder 사용할 있지만 단순한 경우에는 + 활용해 직접 합쳐도 된다.
- 수정할 경우, 수정마다 매번 새로운 객체를 생성함.

2. StringBuffer StringBuilder 차이점
2-1. 특징
- 기본적으로 클래스가 제공하는 메소드는 동일하지만 StringBuffer 멀티 쓰레드 상태에서 동기화를 지원한다. ( 메소드 별로 synchronized 키워드가 존재)
- String + 활용해 합치는 경우 매번 인스턴스를 생성하기 때문에 성능상에 이슈가 많다. 이런 성능 이슈를 개선하기위해 JDK 1.5 버전 이후에는 컴파일 단계에서 StringBuilder 컴파일 되도록 변경되기 때문에 + 활용해도 성능상에 이슈는 없다.

3. 추가내용
3-2. String 클래스는 변경이 불가능한 immutable 클래스이다.
- StringBuffer 클래스가 String 클래스 보다 항상 나은 성능을 가지고 있다면 자바를 설계한 사람들은 String 클래스를 기본 문자열처리 클래스로 정했을까?
- substring(), toLowerCase(), concat(), trim() 등의 메소드를 생각하면 String 클래스는 변경이 가능한 클래스처럼 보이지만 실제로는 이러한 메소드들은 원래 객체와 다른 새로운 String 객체를 만들어 반환한다. 하나의 String 객체가 생성되기 때문에 원래 String 객체는 가지고 있는 문자열이 변경되지 않으며 여전히 사용가능한 채로 남는다.
- 아래와 같은 코드에서 String new 연산은 n 실행된다.
String result = "";
for (int i=0; i < n; i++) {
result += target;
}
- 위와 같은 이유로 Strgin 클래스의 변경은 객체를 생성하기 위하여 시스템(시간, 메모리 ) 낭비한다고 생각되는 경향이 있다.

3-3. immutable(변경불가) 클래스인가?
3-3-1. immutable 클래스의 특징
1) 클래스가 가지고 있는 (String 클래스에서 문자열) 오직 생성자에서만 생성될 있으며, 값을 변경할 있는 어떠한 메소드도 가지고 있지 않아야 한다. 만약 변경을 원한다면, 원하는 값을 가진 새로운 객체를 생성한다.
2) 변경은 적고 읽기(문자열의 참조) 많은 경우, 또는 여러 쓰레드나 객체에서 공유하는 경우 synchronization(동기화) 같은 특별한 안정장치 없이도 안전하게 공유될 있다.
3) 대부분의 문자열이 복잡한 문자열 처리과정보다는 한번 설정된 문자열들을 여러 곳에서 공유하는 경우가 많으므로 자바에서 기본 문자열을 처리하는 클래스로 String 클래스를 immutable 패턴으로 설정하였다.

3-4. StringBuffer 클래스는 변경이 가능한 Mutable 클래스이다.
3-4-1. 특징
- append(), insrt(), delete() 등의 메소드를 통하여 StringBuffer 객체가 가지고 있는 문자열을 변경 있으며, 이때, String 클래스 처럼 새로운 객체를 생성하지 않고 기존의 문자열을 변경한다.
- 아래 코드에서 StringBuffer new 연산자가 한번만 실행된다.
StringBuffer result = new StringBuffer();
for(int i=0; i < n; i++) {
result.append(target);
}
- 위와 같은 경우 객체 생성을 하지 않으므로, String 클래스 보다 효율적이라고 생각하기쉽지만 동기화(synchronization) 보장해야 하기 때문에 단순한 참조에서는 상대적으로 String 보다 나쁜 성능을 보인다.
- 따라서 단순 참조가 많은 경우 StringBuffer 클래스보다 String 클래스가 유리하다. 물론, StringBuffer 클래스는 종기화 되어 있으므로 멀티쓰레드에 대하여 안전하다.
- 또한, StringBuffer 객체는 문자열을 다루는 다른 메소드들에서 사용되기 위하여, toString() 메소드를 통하여 String 객체를 생성하게 된다. 이때, 일반적으로 String 객체의 생성과 함께, 가지고 있는 문자열에 대한 복사가 이루어진다. 물론, 자바 규약은 성능 향상을 위하여 String 객체의 생성 후에 문자열을 복사하지 않고 StringBuffer 객체와 문자열을 공유하여 참조하는 프록시 패턴을 적용하는 것을 허용하고 있다. 그러나 이것은 반드시 그런 것은 아니며, 프록시 패턴의 특성상 StringBuffer 객체에 변경이 가해지면 프록시는 바로 해제되며 시점에서 문자열의 복사가 이루어 진다. (프록시 패턴의 적용은 필수 요건이 아니며, 자바 가상 머신 구현체에 따라 다를 있으며, 사용상의 차이는 전혀 없고 성능상의 차이만을 보일 뿐이다.)

3-5. 성능 향상에 대한 결론
- StringBuffer 클래스는 문자열을 추가하기 위하여 append() 같은 메소드를 사용할 String 클래스보다 뛰어난 성능을 보인다. 그러나 StringBuffer 객체의 생성 toString() 메소드를 통한 String 객체의 생성을 반드시 필요로 하므로 많은 시간 메모리 자원의 낭비를 초래한다.
- String 클래스는 StringBuffer 클래스와 비교하여 인스턴스화를 통하여 객체를 생성할 상대적으로 적은 자원을 소모하며, toString() 메소드를 통하여 String 객체로 바꿀 필요가 없다.
- StringBuffer 클래스는 하나의 문자열에 대하여 다른 문자나 문자열의 추가가 여러 이루어 지는 경우 유리하며, 한번의 문자열 추가에 대하여 StringBuffer 클래스를 사용하는 것은 오히려 시간 메모리 자원 낭비를 초래하게 된다.
- 단순히 StringBuffer 클래스가 soString() 통해 새로운 String 객체 생성이 필요 없다고 가정하면, String + 연산자는 횟수가 많아지면 사용이 불가능 정도로 성능이 좋지 않다. 때문에 문자열을 가지고 일이 많다면 반드시 StringBuffer() 멀티쓰레드로 동기화를 고려하지 않는다면 StringBuilder() 사용하도록 하자.
4. 참고
http://leegaworld.tistory.com/8
- http://javacan.tistory.com/entry/39
- http://deblan2.egloos.com/viewer/419830


댓글

이 블로그의 인기 게시물

Directory FileName Sort

C#에서 Directory.GetFiles(<Path>) 에서 파일명으로 Sort를 할필요성이 있다. Files 배열을 받아서 Sort를 할수도 있지만, Directory class 에서 Sort 기능도 제공을 하는데, LINQ에 Sort 기능을 제공한다. To sort by name, var sorted = Directory . GetFiles ( "." ). OrderBy ( f => f ); To sort by size, var sorted = Directory . GetFiles ( "." ). OrderBy ( f => new FileInfo ( f ). Length ); 참고   http://stackoverflow.com/questions/6294275/sorting-the-result-of-directory-getfiles-in-c-sharp

MongoDB 백업 및 복구방법

MongoDB 백업 및 복구방법 MongoDB 데이터 저장 디렉토리 설정(Windows) -> 보통 Default 로 "C:\data\db\" 로 지정되나, 혹시 디렉토리 설정을 바꿔서 모를경우에는 아래와 같이 명령어를 통해서 확인한다. mongodb --dbpath [arg-path] mongodb -v 명령어를 통해서 dbpath 경로를 확인할수 있다. local dump # mongodump -d [dbname] -o [dirname] Remote dump # mongodump --host mongodb1.example.net --port 37017 --username user --password pass /opt/backup/mongodump-2011-10-24 Mongorestore # mongorestore -h 127.0.0.1 "D\mongoDB\"

C# Namespace Naming Guidelines

The general rule for naming namespaces is to use the company name followed by the technology name and optionally the feature and design as follows. CompanyName.TechnologyName[.Feature][.Design] For example: Microsoft.Media Microsoft.Media.Design Prefixing namespace names with a company name or other well-established brand avoids the possibility of two published namespaces having the same name. For example,  Microsoft.Office  is an appropriate prefix for the Office Automation Classes provided by Microsoft. Use a stable, recognized technology name at the second level of a hierarchical name. Use organizational hierarchies as the basis for namespace hierarchies. Name a namespace that contains types that provide design-time functionality for a base namespace with the  .Design  suffix. For example, the  System.Windows.Forms.Design Namespace  contains designers and related classes used to design  System.Windows.Forms...