문제

그 말을 출력하려면 또는 concat 문자열입니다.다음 스타일을 사용하시겠습니까?

  • var p = new { FirstName = "Bill", LastName = "Gates" };

  • Console.WriteLine("{0} {1}", p.FirstName, p.LastName);

  • Console.WriteLine(p.FirstName + " " + p.LastName);

당신은 오히려 형식으로 사용하거나 당신은 단순히 concat 문자열?좋아하는 무엇입니까?은 이들 중 하나는 상처 당신의 눈?

당신은 합리적인 인수 중 하나를 사용하지 않고 다른?

나는 두 번째 하나입니다.

도움이 되었습니까?

해결책

이 코드입니다.

그것은 약간 수정된 버전의의 코드입니다.
1.내가 제거됩니다.WriteLine 로 그것은 아마 몇 배나 더 느린 보다 내가 무슨 노력을 측정합니다.
2.내가 시작하는 스톱워치기 전에는 루프 및 중지 한 후에 바로 그것을,이 방법으로 난 잃은 정밀도하는 경우 이 함수는 예를 들어 26.4 틱를 실행할 수 있습니다.
3.을 결과에 의해 일부 반복이 잘못 되었습니다.무슨 일이 있을 경우 1000 밀리초과 100 밀리초 미만입니다.두 상황에서,당신은 당신을 얻을 것이 0ms 후로 나누어 1000000.

Stopwatch s = new Stopwatch();

var p = new { FirstName = "Bill", LastName = "Gates" };

int n = 1000000;
long fElapsedMilliseconds = 0, fElapsedTicks = 0, cElapsedMilliseconds = 0, cElapsedTicks = 0;

string result;
s.Start();
for (var i = 0; i < n; i++)
    result = (p.FirstName + " " + p.LastName);
s.Stop();
cElapsedMilliseconds = s.ElapsedMilliseconds;
cElapsedTicks = s.ElapsedTicks;
s.Reset();
s.Start();
for (var i = 0; i < n; i++)
    result = string.Format("{0} {1}", p.FirstName, p.LastName);
s.Stop();
fElapsedMilliseconds = s.ElapsedMilliseconds;
fElapsedTicks = s.ElapsedTicks;
s.Reset();


Console.Clear();
Console.WriteLine(n.ToString()+" x result = string.Format(\"{0} {1}\", p.FirstName, p.LastName); took: " + (fElapsedMilliseconds) + "ms - " + (fElapsedTicks) + " ticks");
Console.WriteLine(n.ToString() + " x result = (p.FirstName + \" \" + p.LastName); took: " + (cElapsedMilliseconds) + "ms - " + (cElapsedTicks) + " ticks");
Thread.Sleep(4000);

사람들은 나의 결과는:

1000000x 결과 문자열.형식("{0} {1}", p.이름,p.LastName);했:618ms-2213706 틱
1000000x result=(p.FirstName+""+p.LastName);했:166ms-595610 틱

다른 팁

는 나는 깜짝 놀라게 그렇게 많은 사람들이 즉시 찾고 싶어하는 코드를 실행합니다. 는 경우 백만 반복 여전히 미만에 두 번째,프로세스가 될 것이 어떤 방법으로 눈에 띄는 최종 사용자에게?매우 가능성이 높습니다.

조 최적화=실패합니다.

나는 가 String.Format 옵션만기 때문에 그에게 가장 의미에서의 건축의 관점에서.나는에 대해 걱정하지 않는 성능까지 그것이 문제가 됩(고 했다면,나는 나 자신에게 물어:해야 합니까를 연결하고 백만 명의 이름을 한 번?반드시 그들은 모두 맞에 대한 최신 정보를 제공합니다.)

을 고려하는 경우 고객중하고 싶어 그것을 변경할 수 있도록 구성 여부를 표시 "Firstname Lastname""Lastname, Firstname." 의 형식은 옵션으로,이것은 쉽게 교체하는 형식 문자열입니다.과 함께 이야 합니다 추가 코드입니다.는 같은 소리 하지 않 큰 이 예제에서는 하지만 추정.

Oh dear-을 읽은 후의 다른 대답을 했어의 순서를 반대의 작업을 수행하도록 연결 첫째,다음의 문자열입니다.형식으로...

Bill Gates
Console.WriteLine(p.FirstName + " " + p.LastName); took: 8ms - 30488 ticks
Bill Gates
Console.WriteLine("{0} {1}", p.FirstName, p.LastName); took: 0ms - 182 ticks

그래서 위의 작업은 엄청난 차이나 오히려 첫 번째 동작은 항상 많은 느립니다.

여기에 결과를 실행하는 작업이 완료됩니다.가 변경하는 명령하지만 일반적으로과 동일한 규칙을 따르면,첫 번째 결과는 무시:

Bill Gates
Console.WriteLine(FirstName + " " + LastName); took: 5ms - 20335 ticks
Bill Gates
Console.WriteLine(FirstName + " " + LastName); took: 0ms - 156 ticks
Bill Gates
Console.WriteLine(FirstName + " " + LastName); took: 0ms - 122 ticks
Bill Gates
Console.WriteLine("{0} {1}", FirstName, LastName); took: 0ms - 181 ticks
Bill Gates
Console.WriteLine("{0} {1}", FirstName, LastName); took: 0ms - 122 ticks
Bill Gates
String.Concat(FirstName, " ", LastName); took: 0ms - 142 ticks
Bill Gates
String.Concat(FirstName, " ", LastName); took: 0ms - 117 ticks

당신이 볼 수 있듯이 이후의 실행의 동일한 방법(I refactor 코드로 3 가지 방법는)점진적으로 더 빠르다.가장 빠르게 나타납니다.WriteLine(문자열입니다.Concat(...))방법에 의해 다음,일반 연결,그리고 그 형식의 작업입니다.

초기에 지연을 시작은 가능성이 초기화 콘솔 스트림으로 배치합니다.Writeline("Start!") 첫 번째 작업 전에 제공한 모든 시간으로 라인입니다.

문자열 변경할 수 없,이미 동일한 작은 조각의 메모리 사용되고 있습니다.추가하여 같은 두 문자열을 함께 만들기 같은 새로운 문자열로 또 다시 영향을 주지 않습니다 메모리입니다..Net 은 충분히 스마트 단지 동일하게 사용하는 메모리 참조.따라서 코드의하지 않는 진정한 테스트 둘 사이의 차이 concat 방법이 있습니다.

이에 대해 크기:

Stopwatch s = new Stopwatch();

int n = 1000000;
long fElapsedMilliseconds = 0, fElapsedTicks = 0, cElapsedMilliseconds = 0, cElapsedTicks = 0, sbElapsedMilliseconds = 0, sbElapsedTicks = 0;

Random random = new Random(DateTime.Now.Millisecond);

string result;
s.Start();
for (var i = 0; i < n; i++)
    result = (random.Next().ToString() + " " + random.Next().ToString());
s.Stop();
cElapsedMilliseconds = s.ElapsedMilliseconds;
cElapsedTicks = s.ElapsedTicks;
s.Reset();

s.Start();
for (var i = 0; i < n; i++)
    result = string.Format("{0} {1}", random.Next().ToString(), random.Next().ToString());
s.Stop();
fElapsedMilliseconds = s.ElapsedMilliseconds;
fElapsedTicks = s.ElapsedTicks;
s.Reset();

StringBuilder sb = new StringBuilder();
s.Start();
for(var i = 0; i < n; i++){
    sb.Clear();
    sb.Append(random.Next().ToString());
    sb.Append(" ");
    sb.Append(random.Next().ToString());
    result = sb.ToString();
}
s.Stop();
sbElapsedMilliseconds = s.ElapsedMilliseconds;
sbElapsedTicks = s.ElapsedTicks;
s.Reset();

Console.WriteLine(n.ToString() + " x result = string.Format(\"{0} {1}\", p.FirstName, p.LastName); took: " + (fElapsedMilliseconds) + "ms - " + (fElapsedTicks) + " ticks");
Console.WriteLine(n.ToString() + " x result = (p.FirstName + \" \" + p.LastName); took: " + (cElapsedMilliseconds) + "ms - " + (cElapsedTicks) + " ticks");
Console.WriteLine(n.ToString() + " x sb.Clear();sb.Append(random.Next().ToString()); sb.Append(\" \"); sb.Append(random.Next().ToString()); result = sb.ToString(); took: " + (sbElapsedMilliseconds) + "ms - " + (sbElapsedTicks) + " ticks");
Console.WriteLine("****************");
Console.WriteLine("Press Enter to Quit");
Console.ReadLine();

샘플 출력:

1000000 x result = string.Format("{0} {1}", p.FirstName, p.LastName); took: 513ms - 1499816 ticks
1000000 x result = (p.FirstName + " " + p.LastName); took: 393ms - 1150148 ticks
1000000 x sb.Clear();sb.Append(random.Next().ToString()); sb.Append(" "); sb.Append(random.Next().ToString()); result = sb.ToString(); took: 405ms - 1185816 ticks

유감이 가난한 번역

는 경우 응용 프로그램이 영어로,다음을 고급 저장 시계 틱.그러나,많은 문화적으로 보 Lastname 이름에서,예를 들면,주소가 있습니다.

그래서 사용 string.Format(), 특히 경우,당신은 이제까지 당신의 응용 프로그램 가 어디서나 영어가 아닌 먼저 언어입니다.

여기에 내 결과 100,000 개 이상 반복:

Console.WriteLine("{0} {1}", p.FirstName, p.LastName); took (avg): 0ms - 689 ticks
Console.WriteLine(p.FirstName + " " + p.LastName); took (avg): 0ms - 683 ticks

그리고 여기에는 벤치 코드:

Stopwatch s = new Stopwatch();

var p = new { FirstName = "Bill", LastName = "Gates" };

//First print to remove the initial cost
Console.WriteLine(p.FirstName + " " + p.LastName);
Console.WriteLine("{0} {1}", p.FirstName, p.LastName);

int n = 100000;
long fElapsedMilliseconds = 0, fElapsedTicks = 0, cElapsedMilliseconds = 0, cElapsedTicks = 0;

for (var i = 0; i < n; i++)
{
    s.Start();
    Console.WriteLine(p.FirstName + " " + p.LastName);
    s.Stop();
    cElapsedMilliseconds += s.ElapsedMilliseconds;
    cElapsedTicks += s.ElapsedTicks;
    s.Reset();
    s.Start();
    Console.WriteLine("{0} {1}", p.FirstName, p.LastName);
    s.Stop();
    fElapsedMilliseconds += s.ElapsedMilliseconds;
    fElapsedTicks += s.ElapsedTicks;
    s.Reset();
}

Console.Clear();

Console.WriteLine("Console.WriteLine(\"{0} {1}\", p.FirstName, p.LastName); took (avg): " + (fElapsedMilliseconds / n) + "ms - " + (fElapsedTicks / n) + " ticks");
Console.WriteLine("Console.WriteLine(p.FirstName + \" \" + p.LastName); took (avg): " + (cElapsedMilliseconds / n) + "ms - " + (cElapsedTicks / n) + " ticks");

그래서 내가 알지 못하는 그의 답변을 표시로 대답:)

연결 문자열에는 간단한 시나리오아-그것은 더 복잡한 아무것도 더 복잡한 보다,심지어 성,이름.형식으로 당신이 볼 수있는,한 눈에서 최종 구조물의 문자열을 읽을 때 코드로 연결 그것은 거의 불가능하게 즉각 분별하고 최종 결과(제외하고는 매우 간단한 예제는 이와 같은).

무엇을 의미하는 장은 당신이 돌아올 때를 변경하여 귀하의 문자열 형식을,당신은 것 중 하나는 능력이 있고 몇 가지 조정하는 형식 문자열,또는 주름 눈썹 및 이동 시작 주위에 숙박 시설의 모든 종류의 접근과 혼합되는 텍스트가 더 가능성이 높을 소개하는 문제입니다.

를 사용하는 경우.NET3.5 확장을 사용할 수 있습니다 방법 다음과 같이나 과를 얻을 쉽게 흐르는,팔목 떨어져 다음과 같은 구문을 사용합니다.

string str = "{0} {1} is my friend. {3}, {2} is my boss.".FormatWith(prop1,prop2,prop3,prop4);

마지막으로,응용 프로그램에서 성장 복잡성을 결정할 수 있습을 미친 듯이 유지하는 응용 프로그램에서 문자열을 이동하려는 그들을 자원으로 파일을 지역화 또는 단순히 정적 도우미입니다.이 될 것입니다 훨씬 쉽게를 달성하면 지속적으로 사용되는 형식,그리고 코드를 수 있는 아주 간단하게 refactor 용

string name = String.Format(ApplicationStrings.General.InformalUserNameFormat,this.FirstName,this.LastName);

아주 간단한 조작 응용 연결,하지만 일단 넘어 2 또는 3 요소 형식이 더 적절한 IMO.

또 다른 이유를 선호하는 문자열입니다.형식입니다.NET 문자열은 변경할 수 없고 그것은 이 방법으로 생성 더 적은 임시/중급 복사본입니다.

는 동안 나는 완전히 스타일을 이해하는 환경 설정 및 연결을 위해 내가 먼저 답변에 따라 부분적으로 내 자신의 취향,나의 결정에 기초한다는 생각을 연결 될 것이 더 빠르다.그래서 호기심,저는 테스트 결과는 엄청난 특히,이러한 작은 문자열입니다.

다음 코드를 사용하면 사용:

    System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();

    var p = new { FirstName = "Bill", LastName = "Gates" };

    s.Start();
    Console.WriteLine("{0} {1}", p.FirstName, p.LastName);
    s.Stop();
    Console.WriteLine("Console.WriteLine(\"{0} {1}\", p.FirstName, p.LastName); took: " + s.ElapsedMilliseconds + "ms - " + s.ElapsedTicks + " ticks");

    s.Reset();
    s.Start();
    Console.WriteLine(p.FirstName + " " + p.LastName);
    s.Stop();

    Console.WriteLine("Console.WriteLine(p.FirstName + \" \" + p.LastName); took: " + s.ElapsedMilliseconds + "ms - " + s.ElapsedTicks + " ticks");

나는 다음과 같은 결과:

Bill Gates
Console.WriteLine("{0} {1}", p.FirstName, p.LastName); took: 2ms - 7280 ticks
Bill Gates
Console.WriteLine(p.FirstName + " " + p.LastName); took: 0ms - 67 ticks

를 사용하여 포맷 방법은 100 개 이상의 시간 느린!!연결지 않도로 등록 1ms 이유입니다,출력 타이머 틱니다.

에 대한 기본 문자열 연결,나는 일반적으로 사용하는 두 번째 스타일을 쉽게 읽고 간단합니다.그러나,경우 나고 더 복잡한 문자열 조합을 나는 일반적으로 선택한 문자열입니다.형식입니다.

문자열입니다.형식으로 저장시에 많은 따옴표와 흑자...

Console.WriteLine("User {0} accessed {1} on {2}.", user.Name, fileName, timestamp);
vs
Console.WriteLine("User " + user.Name + " accessed " + fileName + " on " + timestamp + ".");

몇 charicters 저장,그러나 내가 생각하기에,이를 들어,형식으로 그것이 많은 청소기입니다.

더 나은 테스트하는 것이 시계 당신의 메모리를 사용하여 성과 CLR 메모리 카운터입니다.나의 이해는 전체적인 이유로 사용할 문자열.형식을 대신하여 연결 문자열에는,이 문자열은 불변,당신은 불필요하게 부담을 주는 쓰레기 수집가는 임시 문자열해야 하는 회수에서 다음 전달합니다.

StringBuilder 과 문자열입니다.서식 있지만,잠재적으로 느린,더 많은 메모리에 효율적입니다.

무엇이 그렇게 나쁜에 대해 문자열 연결?

일반적으로 선호 전으로,특히 문자열을 얻을 수 있습이 훨씬 더 쉽게 읽을 수 있습니다.

다른 혜택은 내가 믿는 하나의 성능,후자는 실제로 수행 2 문자열 창조 문을 통과하기 전에 최종습니다.쓰기 방법입니다.문자열입니다.형식을 사용하 StringBuilder 에서 나는 믿고,그래서 여러 연결 방지할 수 있습니다.

주목해야 한다 그러나는 경우에는 매개변수는 당신이에서 전달하는 문자열입니다.형식(과 같은 다른 방법은 다음과 같 Console.쓰)은 값의 형태 그리고 그들은 박스 앞에서 통과를 제공할 수 있는 자신의 성능니다. 블로그 포스팅에 이기.

일주일에서 지금 Aug19,2015,이 질문을 정확하게 될 것입 seven(7)세입니다.이제는 더 좋은 방법이 있습니다. 의 관점에서 유지 관리로 나가지 않은 어떤 성능 테스트하면 문자열을 연결(하지만 그것은 중요한 일입니까?몇 밀리초 단위에는 차이가?).의 새로운 방법으로 그 일 C#6.0:

var p = new { FirstName = "Bill", LastName = "Gates" };
var fullname = $"{p.FirstName} {p.LastName}";

이 새로운 기능 ,IMO,고 실제로 더 나은 우리의 경우 우리는 코드를 우리를 구축 쿼리 문자열 값에 따라 달라지는 일부 요소입니다.상상 쿼리문자열에는 우리가 6 인수입니다.그래서 대신의 일을,예를 들어:

var qs = string.Format("q1={0}&q2={1}&q3={2}&q4={3}&q5={4}&q6={5}", 
    someVar, anotherVarWithLongName, var3, var4, var5, var6)

에서 작성할 수 있습 다음과 같이고 그것은 쉽게 읽을 수 있습니다.:

var qs=$"q1={someVar}&q2={anotherVarWithLongName}&q3={var3}&q4={var4}&q5={var5}&q6={var6}";

에서 시작 C#6.0 삽입된 문자열 을 수행하는 데 사용될 수 있습니다 이를 단순화 형식으로도 더.

var name = "Bill";
var surname = "Gates";
MessageBox.Show($"Welcome to the show, {name} {surname}!");

는 삽입된 문자열 표현처럼 보이는 템플릿 문자열을 포함하는 식입니다.는 삽입된 문자열 표현을 만듭 문자열에 의해 교체를 포함하는 식으로 ToString represenations 의 표현이'결과입니다.

삽입된 문자열이 비슷한 성능을 문자열입니다.포맷하지만,가독성이 향상되고 짧은 구문,사실로 인해하는 값과 표현에 삽입니다.

또한 참조하십시오 이 dotnetperls 문서 에서 문자열이터이다.

을 찾는 경우에는 기본 형식을 지정하는 방법 당신의 문자열이 의미가 측면에서의 가독성과 성능(는 경우를 제외하고 마이크로초 단위로 이 차이를 만들려서는 특정 사용하는 경우).

  1. 포맷입니다".NET"의 방법으로 하고 있습니다.특정팩터링 도구(리팩터링!한)를 제안하는 리팩터링 concat 스타일 코드를 사용하여 포맷 스타일입니다.
  2. 포맷을 쉽게 최적화를 위한 컴파일러(지만 둘째 아마 리팩터링을 사용하는'Concat'하는 방법은 빠르다).
  3. 식은 일반적으로 명확하게 읽기를(특히"fancy"서식).
  4. 포맷을 의미 암시적으로 호출'.ToString'에 모든 변수들을 위해 좋은 가독성을 높입니다.
  5. 에 따라"효과적인 C#",니다.순'WriteLine'과'형식의 구현은 엉망으로,그들은 자동 박스는 모든 가치 유형(나쁜)."효과적인 C#"라고 조언하기행'.ToString'호출을 명시적으로는 이럴조(참조하십시오 Jeff 게시)
  6. 순간에 서식,유형에 힌트를 확인되지 않은 컴파일러에 의해의 결과로 런타임 오류가 있습니다.그러나,이 될 수 있을 개정할 수 있습니다.

나는 사용할 문자열.형식,그러나 나는 것 또한 형식 문자열에는 리소스 파일을 수 있습니다 그래서 현지화를 위해 다른 언어가 있습니다.를 사용하여 간단한 문자열 concat 허용하지 않습니다.분명히면 당신은 늘 필요한 위치를 파악하는 문자열이지 않는 이유에 대해 생각합니다.그것은 정말에 따라 어떤 문자열이다.

는 경우에 그것을 사용자,사용할 문자열.형식할 수 있도록 지역화해야 하는 경우-고 FxCop 주문 확인 그것은 나를 위해 경우에는 그냥:)

이 포함된 경우에는 숫자나 다른 문자열이 아닌 것(예:날짜),사용할 문자열.형식으로 제공하기 때문에 더 나 제어 서식.

면 그것의 건축을 위한 쿼리를 같이 SQL,난 사용 Linq.

는 경우 연결 문자열 루프 안에,내가 사용하십시 StringBuilder 성능 저하를 방지 하기 위해 문제입니다.

는 경우에는 그것의 일부를 출력하는 사용자를 볼 수 있고,없을 효과 성능 사용할 문자열.형식이기 때문에 나는 습관에서 사용하는 어쨌든 난 그냥 그것을 사용:)

만약 당신이 다루는 뭔가가 될 필요가 있는 읽기 쉽게(그리고 이것은 대부분의 코드),나 가진 지팡이 운영자 과부하 버전지 않습니다.

  • 코드는 실행할 필요가 있는 수백만의 시간
  • 당신이 하고 있는 톤의 concats(4 개 이상의 톤)
  • 코드를 대상으로 Compact Framework

에서 두 개 이상의 상황에서,내가 사용하는 것 StringBuilder 대신 합니다.

나는 선택에 기반한 가독성을 높입니다.내가 선호하는 형식 옵션이있을 때 어떤 텍스트 주위에 이 변수입니다.이 예에서는 다음과 같습니다.

Console.WriteLine("User {0} accessed {1} on {2}.", 
                   user.Name, fileName, timestamp);

당신이 이해한 의미도 없는 변수 이름에는 반면,concat 은 복잡 따옴표와+표시와 혼동하는 내 눈:

Console.WriteLine("User " + user.Name + " accessed " + fileName + 
                  " on " + timestamp + ".");

(나는 마이크 빌리의 예를 좋아하기 때문에 나는 그것)

는 경우 형식 문자열이 의미하지 않는없이 많은 변수 이름이 시작하는 명령을 사용할 수 있습니다 concat:

   Console.WriteLine("{0} {1}", p.FirstName, p.LastName);

형식 옵션을 읽거나 내가 변수 이름과 지도 그들을 해당하는 숫자입니다.이 옵션을 필요로하지 않는다.나는 여전히 혼동해서는 따옴표와+표시,그러나 대안은 더 나쁘다.Ruby?

   Console.WriteLine(p.FirstName + " " + p.LastName);

성능 현명한 것으로 예상하는 것과 형식 옵션은 속도가 느린되 그런 다음 이기 때문 형식이 필요할 문자열 구문 분석.내가 기억하지 못하는 이를 최적화하는 명령어의 종류,그러나 내가 그랬다면,내가 보기에 string 과 같은 방법 Concat()Join().

다른 활용과 형식은 format 문자열을 사용할 수 있습에 넣어 구성 파일입니다.매우 편리한 오류 메시지와 UI 텍스트입니다.

하려는 경우에는 로컬라이제이션 결과,다음 문자열입니다.형식은 필수적이기 때문에 서로 다른 언어 자연되지 않을 수도 있습니다 데이터와 같은 순서.

내 생각이 크게 의존하는 방법에 대한 복잡한 출력입니다.나를 선택하는 경향이 어느 시나리오 작품이 가장 좋습니다.

데 올바른 도구를 기반으로 작업:D 든 보이는 가장 깨끗한!

내가 선호하는 두 번째뿐만 아니라 하지만 나는 아무 인수 합리적인 이 시점에서 지원하는 위치입니다.

Nice one!

단가

        s.Start();
        for (var i = 0; i < n; i++)
            result = string.Concat(p.FirstName, " ", p.LastName);
        s.Stop();
        ceElapsedMilliseconds = s.ElapsedMilliseconds;
        ceElapsedTicks = s.ElapsedTicks;
        s.Reset();

고 심지어는 더 빠르(나는 문자열입니다.Concat 이라는 두 가지 예제에서,하지만 첫 번째 중 하나가 필요 합 일종의 번역).

1000000 x result = string.Format("{0} {1}", p.FirstName, p.LastName); took: 249ms - 3571621 ticks
1000000 x result = (p.FirstName + " " + p.LastName); took: 65ms - 944948 ticks
1000000 x result = string.Concat(p.FirstName, " ", p.LastName); took: 54ms - 780524 ticks

이후 나는 생각하지 않는 답변이 여기에 모든 것을 커버하고 싶은 또한 여기에.

Console.WriteLine(string format, params object[] pars) 전화 string.Format.에'+'을 의미한 문자열 연결.나는 생각하지 않는 이 항상 함께 할 수 있는 스타일;내가 혼합하는 경향이있는 두 가지 스타일에 따라 컨텍스트 내에서.

짧은 대답

결정하고 당신이 직면하는 문자열을 할당.수 있도록 노력하겠습니다 그것은 간단합니다.

당신

string s = a + "foo" + b;

을 실행하는 경우 이 평가는 다음과 같다:

string tmp1 = a;
string tmp2 = "foo" 
string tmp3 = concat(tmp1, tmp2);
string tmp4 = b;
string s = concat(tmp3, tmp4);

tmp 여기에는 정말로 지역 변수이지만,그것은 임시 위한 JIT(그것은 밀어에 IL stack).는 경우 밀어 문자열에 스택(예: ldstr IL 리터럴)을 참조하여 문자열에 포인터를 놓습니다.

그 순간을 전화 concat 이 참조 문제가 없기 때문에,어떤 문자열을 참조할 수 있 모두 포함하는 문자열입니다.이 의미합니다.NET 할당을 필요로 하는 새로운 블록의 메모리한 다음 그것을 채우기와 두 개의 문자열입니다.이 문제이기 때문에 할당은 상대적으로 비싸다.

변경되는 질문:할 수 있는 방법 당신의 수를 줄일 concat operations?

그래서,거친 대답입니다: string.Format 대>1concats,'+'잘 작동을 위한 1concat.과하지 않는 경우에 대해 관심을 하기 마이크로 성능 최적화, string.Format 이에서 잘 작동하는 일반적인 경우.

에 대한 참고 문화

그리고 거기라는 것입니다.

string.Format 를 사용할 수 있습 CultureInfo 에서 당신의 서식을 지정합니다.간단한 운영자에'+'사용하여 현재 문화입니다.

이것은 특히 중요한 말을 쓰는 경우 파일 형식 및 f.ex. double 는 값은'추가'하는 문자열을 사용합니다.다른 시스템에서,당신은 끝낼 수 있습니다 다른 문자열을 사용하지 않는 경우 string.Format 이 명시적으로 CultureInfo.

F.ex.어떻게 고려하십시오를 변경하는 경우에는'.'한','쓰는 동안 당신의 쉼표로 구분한 값이 파일의...네덜란드 소수 구분 기호는 쉼표로,그래서 당신의 사용자가를 얻을 수 있습니는'재미있는'놀라움이다.

더욱 자세한 응답

알지 못하는 경우 정확한 문자열 크기 사전에,그것은 최고의 정책을 사용하여 다음과 같이 overallocate 버퍼를 사용할.는 여유 공간이 먼저 채워진 후에,데이터 복사합니다.

성장하는 수단을 할당하는 새로운 블록의 메모리고 복사하는 오래된 데이터를 새로운 버퍼입니다.이전 블록의 메모리할 수 있습니다.당신이 얻은 결론에 이점:성장은 비용이 많이 드는 작업.

가장 실제적인 방법이 사용하는 overallocation 정책입니다.가장 일반적인 정책을 overallocate 버퍼에서의 능력 2.물론 당신은 그것을 조금 더 똑똑하다는 것(이후 그것은 아무 의미에서 성장하는 1,2,4,8 는 경우에 당신은 이미 당신이 알고 있을 필요 128chars)하지만 당신은 그림을 얻는다.정책 보장할 필요가 없다 너무 많은 비싼 작업을 설명한다.

StringBuilder 클래스는 기본적으로 overallocates 기본 버퍼에 힘입니다. string.FormatStringBuilder 습니다.

이것은 당신의 결정은 기본적인 사 overallocate 및 추가(여)(w/w.o.문화)또는 할당 및 추가합니다.

개인적으로 두 번째 중 하나로 모든 것을 당신이 사용하는에서 직접 순서 출력됩니다.반면 첫 번째로 당신을 일치{0}과{1}적절한 var 하기 쉽습니다.

적어도 그것으로 나쁘지 않는 C++sprintf 가를 얻을 경우 변수가 형식이 잘못 전체를 날려 버릴 것입니다.

또한,이후 두 번째입니다 모든 인라인하고 그것을 해야 하지 않는 어떤 검색 및 교체를 위해 모든{0}것,후반은 빠르게 처리 될 수 있습니다...지 확실히 알 수 있습니다.

으로 첫 번째 중 하나 때문에 있을 때에는 많은 변수가 섞여 텍스트와 함께 쉬운 것을 나에게 읽어 보시기 바랍니다.게다가,그것은 다루기 쉽게 따옴표를 사용할 때 문자열입니다.형식(),uh,형식입니다.기 제 분석 의 문자열 연결.

난 항상 사라의 문자열입니다.형식()노선입니다.저장할 수 있는 것도 포맷에서 같은 변수를 나단의 예에는 것은 큰 장점이다.어떤 경우에도 추가한 변수이지만 한 번 이상 1 변수에 연결되었을 나는 리팩터를 사용하여 포맷됩니다.

아,그리고 그 이해의 완성도를 높이기 위해서는 다음은 몇 가지보다 더 빨리 정상적인 연결:

Console.WriteLine(String.Concat(p.FirstName," ",p.LastName));

첫 번째 하나를(형식)더 잘 보이는다.더 읽을 수 있고 당신을 생성하지 않은 추가 임시 문자열이다.

제가 궁금했는 StringBuilder 서으로 이러한 테스트합니다.결과는 아래...

class Program {
   static void Main(string[] args) {

      var p = new { FirstName = "Bill", LastName = "Gates" };

      var tests = new[] {
         new { Name = "Concat", Action = new Action(delegate() { string x = p.FirstName + " " + p.LastName; }) },
         new { Name = "Format", Action = new Action(delegate() { string x = string.Format("{0} {1}", p.FirstName, p.LastName); }) },
         new { Name = "StringBuilder", Action = new Action(delegate() {
            StringBuilder sb = new StringBuilder();
            sb.Append(p.FirstName);
            sb.Append(" ");
            sb.Append(p.LastName);
            string x = sb.ToString();
         }) }
      };

      var Watch = new Stopwatch();
      foreach (var t in tests) {
         for (int i = 0; i < 5; i++) {
            Watch.Reset();
            long Elapsed = ElapsedTicks(t.Action, Watch, 10000);
            Console.WriteLine(string.Format("{0}: {1} ticks", t.Name, Elapsed.ToString()));
         }
      }
   }

   public static long ElapsedTicks(Action ActionDelg, Stopwatch Watch, int Iterations) {
      Watch.Start();
      for (int i = 0; i < Iterations; i++) {
         ActionDelg();
      }
      Watch.Stop();
      return Watch.ElapsedTicks / Iterations;
   }
}

결과:

Concat: 406 ticks
Concat: 356 ticks
Concat: 411 ticks
Concat: 299 ticks
Concat: 266 ticks
Format: 5269 ticks
Format: 954 ticks
Format: 1004 ticks
Format: 984 ticks
Format: 974 ticks
StringBuilder: 629 ticks
StringBuilder: 484 ticks
StringBuilder: 482 ticks
StringBuilder: 508 ticks
StringBuilder: 504 ticks

에 따라 MCSD 준비재,Microsoft 제안을 사용하면 운영자는 다룰 때는 아주 적은 수의 연결(아마 2~4).나는 여전히지만,그것은 무언가를 고려해야 합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top