StringBuilder를 언제 사용해야합니까?
-
22-07-2019 - |
문제
StringBuilder의 이점을 이해합니다.
그러나 2 줄을 연결하려면 StringBuilder없이 수행하는 것이 더 좋습니다. 이 올바른지?
어떤 시점에서 (줄 수) StringBuilder를 사용하는 것이 더 좋습니까?
해결책
따뜻하게 읽을 것을 제안합니다 마이크로 최적화 극장의 슬픈 비극, Jeff Atwood.
그것은 간단한 연결 대 StringBuilder 대 기타 방법을 취급합니다.
이제 숫자와 그래프를보고 싶다면 링크를 따르십시오;)
다른 팁
그러나 2 줄을 연결하고 싶다면 StringBuilder없이 수행하는 것이 더 좋습니다. 이 올바른지?
그것은 실제로 정확합니다. 왜 정확하게 설명 된 이유를 찾을 수 있습니다.
http://www.yoda.arachsys.com/csharp/stringbuilder.html
요약 : 당신이 한 번에 현을 연결할 수 있다면
var result = a + " " + b + " " + c + ..
사본만으로 문자열 빌더가 없으면 더 좋습니다 (결과 문자열의 길이는 미리 계산됩니다.);
같은 구조
var result = a;
result += " ";
result += b;
result += " ";
result += c;
..
새 개체는 매번 생성되므로 StringBuilder를 고려해야합니다.
결국 기사는 다음과 같은 경험을 요약합니다.
경험의 규칙
그렇다면 언제 StringBuilder를 사용해야하고 언제 문자열 연결 연산자를 사용해야합니까?
사소한 루프에서 연결을 할 때 StringBuilder를 사용하십시오. 특히 루프를 통해 얼마나 많은 반복을 할 수 있는지 확실히 알지 못하는 경우. 예를 들어, 한 번에 문자 파일을 읽고 += 연산자를 사용하면서 문자열을 구축하는 것은 잠재적으로 성능 자살입니다.
하나의 문서에 연결해야 할 모든 것을 지정할 수있을 때 연결 연산자를 확실히 사용하십시오. (구분자가 필요한 경우 string.concat을 명시 적으로 호출하는 것을 고려하십시오.)
리터럴을 여러 개의 연결 비트로 부수는 것을 두려워하지 마십시오. 결과는 동일합니다. 예를 들어 성능에 해를 끼치 지 않고 긴 문자를 여러 줄로 나누어 가독성을 도울 수 있습니다.
다음에 연결을 반복하는 것 외에 다른 것에 대한 중급 결과가 필요한 경우 StringBuilder가 도움이되지 않습니다. 예를 들어, 이름과 성에서 전체 이름을 구축 한 다음 끝에 세 번째 정보 (별명, 아마도)를 추가하면 StringBuilder를 사용하면 혜택을받지 않으면 혜택을받을 수 있습니다. 다른 목적으로 (이름 + 성) 문자열이 필요합니다 (사람 객체를 만드는 예에서와 같이).
할 일이 몇 가지 있고 별도의 진술로 실제로하고 싶다면 실제로 어떤 방식 으로든 상관 없습니다. 어떤 방식으로 더 효율적인 지에 따라 관련된 문자열의 크기와 관련된 순서에 따라 달라집니다. 실제로 그 코드 조각이 성능 병목 현상, 프로파일 또는 벤치마킹이라고 생각한다면 두 가지 방법을 두 가지 방법으로 벤치마킹합니다.
System.String은 불변의 객체입니다. 이는 콘텐츠를 수정할 때마다 새 문자열을 할당하면 시간 (및 메모리)이 필요하다는 것을 의미합니다. StringBuilder를 사용하면 새 컨텐츠를 할당하지 않고 객체의 실제 내용을 수정합니다.
따라서 문자열에서 많은 수정을해야 할 때 StringBuilder를 사용하십시오.
실제로 ... 크기가 큰 문자열 또는 루프와 같이 많은 동의가 있습니다.
결정적인 대답은없고, 단지 규칙 만 있습니다. 내 자신의 개인 규칙은 다음과 같이됩니다.
- 루프에서 연결하는 경우 항상 a를 사용하십시오
StringBuilder
. - 문자열이 크면 항상 사용하십시오
StringBuilder
. - 연락 코드가 화면에서 깔끔하고 읽을 수 있다면 아마 괜찮을 것입니다.
그렇지 않은 경우 aStringBuilder
.
역설에
그런 다음 너는 세 명으로 세어 더 이상, 그 이상을 세지 말라. 세 사람은 당신이 수를 세었고, 계산의 수는 3이됩니다. 네가 세지 않고, 너는 둘을 세지 않아도, 너는 세 명으로 나아가는 것을 제외하고. 세 번째 숫자 인 세 번째 숫자가 한 번 도달 한 다음, 당신의 거룩한 손 수류탄의 로브 베어스
나는 일반적으로 모든 코드 블록에 String Builder를 사용하여 3 개 이상의 문자열이 연결됩니다.
- 루프에서 문자열을 연결하는 경우 일반 문자열 대신 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
그러나 2 줄을 연결하고 싶다면 StringBuilder없이 그렇게하는 것이 더 좋고 빠르다고 가정합니다. 이 올바른지?
예. 그러나 더 중요한 것은 훨씬 더 중요합니다 읽을 수 있습니다 바닐라를 사용합니다 String
그런 상황에서. 반면에 그것을 루프로 사용하는 것은 의미가 있으며, 또한 합리적이며, 또한 합의만큼 읽을 수 있습니다.
나는 임계 값으로 특정 수의 연결을 인용하는 엄지 규칙에주의를 기울일 것입니다. 루프 (및 루프 만)에 사용하는 것은 아마도 유용하고 기억하기 쉽고 더 합리적 일 것입니다.
연결 수 (A + B + C ...)를 물리적으로 입력 할 수있는 한 큰 차이를 만들어서는 안됩니다. n Squared (n = 10)는 100 배의 속도가 낮아서 너무 나쁘지 않아야합니다.
가장 큰 문제는 수백 줄을 연결하는 것입니다. n = 100에서는 10000 배 속도가 느려집니다. 꽤 나쁘다.
나는 언제 사용 해야하는지 또는 그렇지 않을 때 사이에 미세한 선이 있다고 생각하지 않습니다. 물론 누군가가 황금 상태로 나오기 위해 광범위한 테스트를 수행하지 않는 한.
나를 위해, 나는 2 개의 거대한 줄을 연결하는 경우 StringBuilder를 사용하지 않을 것입니다. 결정적이지 않은 카운트가있는 루프가 있다면 루프가 작은 카운트 일지라도 가능성이 높습니다.
단일 연결은 StringBuilder를 사용하는 가치가 없습니다. 나는 일반적으로 경험상 5 개의 연결을 사용했습니다.
그만큼 StringBuilder 클래스는 개발자에게 변이 가능한 문자열을 조작 할 수있는 일련의 메소드를 제공하며 새 개체를 만들지 않고 문자열을 수정하려면 사용할 수 있으므로 일반 문자열 연결의 오버 헤드 또는 병목 현상 문제를 제거합니다.
사용 StringBuilder 많은 문자열을 루프로 연결할 때 클래스는 성능을 향상시킬 수 있습니다.
다음은 .NET의 StringBuilder 클래스를 사용하여 문자열을 조작하기 위해 수행 할 수있는 몇 가지 작업 목록입니다.
추가: 현재 StringBuilder의 끝에 정보를 추가합니다.
부록: 문자열로 전달 된 형식 지정자를 형식 텍스트로 대체합니다.
끼워 넣다: 현재 StringBuilder의 지정된 색인에 문자열 또는 객체를 삽입합니다.
제거하다: 현재 StringBuilder에서 지정된 수의 문자를 제거합니다.
바꾸다: 지정된 인덱스에서 지정된 문자를 대체합니다.