IT이야기

StringBuilder 대 StringWriter 및 PrintWriter의 문자열 어셈블리

cyworld 2021. 4. 13. 21:49
반응형

StringBuilder 대 StringWriter 및 PrintWriter의 문자열 어셈블리


나는 최근에 전에 본 적이없는 관용구 인 StringWriter와 PrintWriter의 문자열 어셈블리를 만났습니다. 나는 그것들을 사용하는 방법을 알고 있지만 항상 StringBuilder를 사용했습니다. 하나를 선호하는 구체적인 이유가 있습니까? StringBuilder 메서드는 나에게 훨씬 더 자연스러워 보이지만 스타일일까요?

여기에 몇 가지 질문 (가장 가까운 StringWriter 또는 StringBuilder 포함 )을 살펴 보았지만 실제로 간단한 문자열 어셈블리에 대해 하나를 선호하는 이유가 있는지 여부에 대한 질문에 대한 답변은 없습니다.

이것은 내가 여러 번보고 사용했던 관용구입니다 : StringBuilder의 문자열 어셈블리 :


    public static String newline = System.getProperty("line.separator");
    public String viaStringBuilder () {
       StringBuilder builder = new StringBuilder();
       builder.append("first thing").append(newline);  // NOTE: avoid doing builder.append("first thing" + newline);
       builder.append("second thing").append(newline);
       // ... several things
       builder.append("last thing").append(newline);
       return builder.toString();
    }

그리고 이것은 새로운 관용구입니다 : StringWriter와 PrintWriter의 문자열 어셈블리 :


    public String viaWriters() {
       StringWriter stringWriter = new StringWriter();
       PrintWriter printWriter = new PrintWriter(stringWriter);
       printWriter.println("first thing");
       printWriter.println("second thing");
       // ... several things
       printWriter.println("last thing");
       printWriter.flush();
       printWriter.close();
       return stringWriter.toString();
    }

편집 다른 것보다 하나를 선호 구체적인 이유 가없는 것 같아서 내 이해와 가장 일치하는 답변을 수락하고 다른 모든 답변을 +1했습니다. 또한 답변 중 하나에 대한 응답으로 내가 실행 한 벤치마킹 결과를 제공하는 내 답변을 게시했습니다. 모두에게 감사합니다.

다시 편집하십시오. 하나 (특히 StringBuilder)를 다른 것보다 선호하는 구체적인 이유 있음이 밝혀졌습니다 . 내가 처음 놓친 것은 개행 문자의 추가였습니다. 개행을 추가하면 (위와 같이 별도의 추가로) 약간 더 빠릅니다. 크지는 않지만 의도의 명확성과 결합하면 확실히 더 좋습니다. 개선 된 타이밍에 대해서는 아래 내 대답을 참조하십시오.


스타일 적으로 StringBuilder접근 방식은 더 깔끔합니다. 코드 줄이 적고 문자열 작성을 위해 특별히 설계된 클래스를 사용하고 있습니다.

다른 고려 사항은 더 효율적입니다. 대답하는 가장 좋은 방법은 두 가지 대안을 벤치마킹하는 것입니다. 그러나 StringBuilder 더 빨라야 한다는 명확한 포인터 있습니다. 우선 StringWriter는 "스트림"에 기록 된 문자를 보관하기 위해 내부적으로 StringBuilder StringBuffer를 사용합니다 .


StringWriter는 문자열에 쓰고 싶지만 Writer 또는 Stream을 예상하는 API로 작업 할 때 사용하는 것입니다. 대안이 아니라 타협입니다. StringWriter는 필요한 경우에만 사용합니다.


좋아, 답이 하나를 선호하는 문체적인 이유를 강조하는 것 같아서 타이밍 테스트를 만들기로 결정했습니다.

편집 : 위의 robinst의 설명에 따라 이제 PrintWriter (StringWriter) 스타일 추가를 수행하는 방법과 StringBuilder를 사용하는 두 가지 방법이 있습니다. 하나는 추가 (원본 builder.append(thing + newline);에서와 같이) 안에 줄 바꿈을 추가 하는 방법입니다. other는 별도의 추가를 수행합니다 (위와 같이 :) builder.append(thing).append(newline);.

나는 일반적인 벤치마킹 계획을 따랐다. 먼저 여러 번 (이 경우에는 1000 번) 메서드를 호출하여 최적화 프로그램이 워밍업 할 시간을 준 다음 각 메서드를 번갈아 가며 여러 번 (이 경우에는 100,000 번) 호출하여 변경 사항이 발생하도록합니다. 워크 스테이션의 런타임 환경에서보다 공정하게 분산되고 테스트 자체를 여러 번 실행하고 결과를 평균화합니다.

아, 물론 생성 된 라인 수와 라인 길이는 무작위로 지정되지만 버퍼 크기 또는 라인 크기가 결과에 미치는 영향을 피하고 싶었 기 때문에 각 호출 쌍에 대해 동일하게 유지됩니다.

이에 대한 코드는 다음과 같습니다. http://pastebin.com/vtZFzuds

참고 : 새 테스트를 반영하기 위해 pastebin 코드를 아직 업데이트하지 않았습니다.

TL, DR? 각 메서드에 대한 100,000 호출의 평균 결과는 매우 유사합니다.

  • StringBuilder를 사용한 호출 당 0.11908ms (괄호 안의 + 줄 바꿈)
  • StringBuilder를 사용한 호출 당 0.10201ms (개행을 별도의 추가로 사용)
  • PrintWriter (StringWriter)를 사용하여 호출 당 0.10803ms

너무 가까워서 타이밍이 나에게 거의 관련이 없기 때문에 문체상의 이유로 StringBuilder (별도의 추가 포함)와 같은 작업을 계속할 것입니다. 물론이 확립되고 성숙한 코드베이스에서 작업하는 동안 놀라움을 최소화하기 위해 대부분 기존 규칙을 유지할 것입니다.


Writers -PrintWriter가 스트림에 씁니다. IOExceptions를 억제하는 것과 같은 이상한 일을합니다. System.out은 이들 중 하나입니다. -StringWriter는 StringBuffer에 쓰는 Writer입니다 (OutputStreams의 ByteArrayOutputStream과 유사).

StringBuilder- 물론 StringBuilder는 단순히 메모리에 문자열을 생성하려는 경우 원하는 것입니다.

결론

Writers by design are meant to push character data out a stream (usually to a file or through a connection) so being able to use Writers to simply assemble strings seems to be a bit of a side effect.

StringBuilder (and its synchronized sibling StringBuffer) are designed to assemble strings (read string bashing). If you look at the StringBuilder API you can see thatnot only can you do vanilla appending but also replace, reverse, insert etc. StringBuilder is your String construction friend.


I see two advantages of the PrintWriter method: (1) You don't have to add " + newline" at the end of every single line, which actually results in shorter code if you have a lot of writing to do. (2) You don't have to call System.getProperty(); you let the PrintWriter worry about what the newline character should be.


in this link : http://nohack.eingenetzt.com/java/java-stringwriter-vs-stringbuilder the author shows that the StringWriter is even slightly faster than the StringBuilder.and also said : "So when bigger amounts of data come into play the StringWriter clearly shows its superiority in performance over the StringBuilder."

ReferenceURL : https://stackoverflow.com/questions/2980805/string-assembly-by-stringbuilder-vs-stringwriter-and-printwriter

반응형