[c#] 언제 StringBuilder를 사용합니까?

StringBuilder의 이점을 이해합니다.

그러나 두 문자열을 연결하려면 StringBuilder없이 수행하는 것이 더 낫다고 가정합니다. 이 올바른지?

어느 시점 (문자열 수)에서 StringBuilder를 사용하는 것이 더 좋습니까?



답변

Jeff Atwood가 쓴 The Sad Tragedy of Micro-Optimization Theatre 를 읽어 보시기 바랍니다 .

Simple Concatenation 대 ​​StringBuilder 대 다른 메서드를 처리합니다.

이제 숫자와 그래프를 보려면 링크를 따르십시오.)


답변

그러나 두 문자열을 연결하려면 StringBuilder없이 수행하는 것이 더 낫다고 가정합니다. 이 올바른지?

그것은 참으로 정확합니다, 당신은 왜 정확하게 설명되었는지 찾을 수 있습니다 :

http://www.yoda.arachsys.com/csharp/stringbuilder.html

요약 : 문자열을 한 번에 연결할 수 있다면

var result = a + " " + b  + " " + c + ..

복사본이 만들어 질 때만 StringBuilder를 사용하지 않는 것이 좋습니다 (결과 문자열의 길이는 미리 계산됩니다.);

같은 구조를 위해

var result = a;
result  += " ";
result  += b;
result  += " ";
result  += c;
..

새 객체는 매번 생성되므로 StringBuilder를 고려해야합니다.

마지막으로이 기사는 이러한 경험 규칙을 요약합니다.

경험의 규칙

그렇다면 언제 StringBuilder를 사용해야하고 언제 문자열 연결 연산자를 사용해야합니까?

  • 사소하지 않은 루프에서 연결할 때 반드시 StringBuilder를 사용하십시오. 특히 루프를 통해 반복 할 수있는 반복 횟수를 (컴파일시) 확실하지 않은 경우 특히 그렇습니다. 예를 들어, 한 번에 한 문자 씩 파일을 읽고 + = 연산자를 사용하여 문자열을 작성하는 것은 잠재적으로 성능 자살입니다.

  • 하나의 명령문에서 연결해야하는 모든 것을 (읽기 쉽게) 지정할 수있는 경우 연결 연산자를 반드시 사용하십시오. (연결할 배열이있는 경우 String.Concat을 명시 적으로 호출하거나 구분 기호가 필요한 경우 String.Join을 호출하는 것이 좋습니다.)

  • 리터럴을 여러 개의 연결된 비트로 나누는 것을 두려워하지 마십시오. 결과는 동일합니다. 예를 들어 성능에 영향을주지 않고 긴 리터럴을 여러 줄로 나누면 가독성을 높일 수 있습니다.

  • 다음 연결 반복을 제공하는 것 이외의 다른 연결에 대한 중간 결과가 필요한 경우 StringBuilder가 도움이되지 않습니다. 예를 들어, 이름과 성에서 전체 이름을 만든 다음 마지막에 세 번째 정보 (별명)를 추가하면 StringBuilder를 사용하지 않는 경우에만 혜택을받을 수 있습니다. 다른 목적을 위해 (이름 + 성) 문자열이 필요합니다 (Person 객체를 생성하는 예제에서와 같이).

  • 몇 개의 연결 만 수행 할 수 있고이를 별도의 문으로 수행하려는 경우 어느 방향으로 가는지는 중요하지 않습니다. 어떤 방법이 더 효율적인지는 관련된 문자열의 크기와 연결되는 순서에 따라 달라집니다. 만약 당신이 정말로 그 코드가 성능 병목 현상이라고 생각한다면 프로파일 링하거나 벤치마킹하십시오.


답변

System.String은 변경 불가능한 개체입니다. 즉, 콘텐츠를 수정할 때마다 새 문자열이 할당되며 시간과 메모리가 필요합니다. StringBuilder를 사용하면 새 개체를 할당하지 않고 개체의 실제 콘텐츠를 수정할 수 있습니다.

따라서 문자열을 많이 수정해야 할 때 StringBuilder를 사용하십시오.


답변

별로 … 문자열 을 연결 하거나 루프와 같이 연결이 많은 경우 StringBuilder를 사용해야합니다 .


답변

  • 루프에서 문자열을 연결하는 경우 일반 문자열 대신 StringBuilder 사용을 고려해야합니다.
  • 단일 연결 인 경우 실행 시간의 차이가 전혀 보이지 않을 수 있습니다.

요점을 증명하는 간단한 테스트 앱은 다음과 같습니다.

class Program
{
    static void Main(string[] args)
    {
        const int testLength = 30000;
        var StartTime = DateTime.Now;

        //TEST 1 - String
        StartTime = DateTime.Now;
        String tString = "test string";
        for (int i = 0; i < testLength; i++)
        {
            tString += i.ToString();
        }
        Console.WriteLine((DateTime.Now - StartTime).TotalMilliseconds.ToString());
        //result: 2000 ms

        //TEST 2 - StringBuilder
        StartTime = DateTime.Now;
        StringBuilder tSB = new StringBuilder("test string");
        for (int i = 0; i < testLength; i++)
        {
            tSB.Append(i.ToString());
        }
        Console.WriteLine((DateTime.Now - StartTime).TotalMilliseconds.ToString());
        //result: 4 ms

        Console.ReadLine();
    }
}

결과 :

  • 30,000 회 반복

    • 문자열-2000ms
    • StringBuilder-4ms
  • 1000 회 반복

    • 문자열-2ms
    • StringBuilder-1ms
  • 500 회 반복

    • 문자열-0ms
    • StringBuilder-0ms


답변

의역하다

그러면 너는 더도 더도 더도 더도 더도 덜도 안된다. 세 개는 세어야 할 숫자이고 세는 수는 세 개입니다. 네가 세지 말고 두 세도 세지 말라. 단 세 명으로 넘어가는 것 외에는 말이다. 세 번째 숫자 인 세 번째 숫자에 도달하면 안티오크의 성스러운 수류탄을 로브 베스트하십시오

나는 일반적으로 세 개 이상의 문자열을 연결하는 코드 블록에 문자열 작성기를 사용합니다.


답변

확실한 답은없고 경험의 규칙 만 있습니다. 내 개인 규칙은 다음과 같습니다.

  • 루프에서 연결하는 경우 항상 StringBuilder.
  • 문자열이 크면 항상 StringBuilder.
  • 연결 코드가 깔끔하고 화면에서 읽을 수 있다면 괜찮을 것입니다.
    그렇지 않은 경우 StringBuilder.