문제

나는 종종 이것을 궁금해했다. 처음에는 문자열에 값을 할당 할 때 가독성을 높이기 위해 여러 줄에 문자열을 분할하는 성능 비용이 있습니까? 나는 문자열이 불변이 없으므로 매번 새로운 문자열을 만들어야한다는 것을 알고 있습니다. 또한, 성능 비용은 실제로 오늘날의 빠른 하드웨어 덕분에 (일부 악마 루프에 있지 않다면) 관련이 없습니다. 예를 들어 :

String newString = "This is a really long long long long long" +
    " long long long long long long long long long long long long " +
    " long long long long long long long long long string for example.";

JVM 또는 .NET의 컴파일러 및 기타 최적화가 어떻게 처리합니까? 단일 문자열이 생성됩니까? 아니면 1 개의 문자열을 생성 한 다음 값을 연결 한 다음 값을 다시 연결하는 새로운 값을 생성합니까?

이것은 내 자신의 호기심을위한 것입니다.

도움이 되었습니까?

해결책

이는 C# 사양에 의해 컴파일 타임 상수이기 때문에 문자열을 단일 리터럴로 작성하는 것과 동일하도록 보장됩니다. C# 3 사양의 7.18 절에서 :

표현이 위에 나열된 요구 사항을 충족 할 때마다 표현식은 컴파일 시간에 평가됩니다. 표현이 비정규 구조를 포함하는 더 큰 표현의 하위 표현이더라도 사실입니다.

( "위에 나열된 요구 사항"의 정확한 세부 사항은 사양을 참조하십시오 :)

Java 언어 사양은 바닥 근처에 그것을 지정합니다. 섹션 3.10.5:

상수 표현식 (§15.28)으로 계산 된 문자열은 컴파일 시간에 계산 된 다음 마치 리터럴 인 것처럼 처리됩니다.

다른 팁

실제로 Java에서는 컴파일러가 String 상수로.

class LongLongString
{
    public LongLongString()
    {
        String newString = "This is a really long long long long long" +
            " long long long long long long long long long long long long " +
            " long long long long long long long long long string for example.";
    }

    public static void main(String[] args)
    {
        new LongLongString();
    }
}

다음과 같이 컴파일됩니다.

Compiled from "LongLongString.java"
class LongLongString extends java.lang.Object{
public LongLongString();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   ldc #2; //String This is a really long long long long long long long long long long long long long long long long long  long long long long long long long long long string for example.
   6:   astore_1
   7:   return

public static void main(java.lang.String[]);
  Code:
   0:   new #3; //class LongLongString
   3:   dup
   4:   invokespecial   #4; //Method "<init>":()V
   7:   pop
   8:   return

}

볼 수 있듯이, 한 줄은 여러 줄이 아닌 4 행에로드됩니다. String 인스턴스가로드 중입니다.

편집하다: 소스 파일을 사용하여 컴파일되었습니다 javac 버전 1.6.0_06. 보고 있습니다 Java 언어 사양, 제 3 판, (그리고 언급 된 동일한 섹션 Jon Skeet의 대답), 컴파일러가 멀티 라인을 연결 해야하는지에 대한 참조를 찾을 수 없었습니다. String 싱글로 String, 이 동작은 아마도 컴파일러 구현에 따라 다릅니다.

직접 테스트하십시오. C# 코드에서 (동등한 Java도 작동합니다) :

string x = "A" + "B" + "C";
string y = "ABC";

bool same = object.ReferenceEquals(x, y); // true

결과가 있음을 알 수 있습니다 true.

옆으로, 당신은 런타임의 문자열 풀에서 문자열이 인턴 된 것을 볼 수 있습니다.

bool interned = object.ReferenceEquals(x, string.Intern(x)); // true

성능 상단 오프가 없습니다. 컴파일러의 최적화는이를 단일 문자열 (적어도 Java)으로 병합합니다.

내가 기억할 수있는 한, 이것은 여러 줄을 만들지 않을 것입니다.

보완 할 .NET IL Coobird의 대답:

C# 코드의 경우 :

string s = "This is a really long long long long long" +
    " long long long long long long long long long long long long " +
    " long long long long long long long long long string for example.";
Console.WriteLine(s);

디버그 컴파일이 생성됩니다.

.method public hidebysig static void Main(string[] args) cil managed
{
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor()
  .maxstack 1
  .locals init (
      [0] string str)
  L_0000: ldstr "This is a really long long long long long long long long long long long long long long long long long  long long long long long long long long long string for example."
  L_0005: stloc.0 
  L_0006: ldloc.0 
  L_0007: call void [mscorlib]System.Console::WriteLine(string)
  L_000c: ret 
}

보시다시피, 그것은 하나의 문자열입니다.

모든 문자열이 일정하는 한 (예에서와 같이) Java (그리고 C#을 상상합니다)로 컴파일러는 이것을 단일 문자열로 변환합니다.

루프와 같은 많은 동적 문자열을 연결하는 경우 +에서만 성능 문제가 발생합니다. 이 경우 StringBuilder 또는 StringBuffer를 사용하십시오.

면책 조항 : 이것은 Java에게 해당됩니다. 나는 C#에 대해 사실을 가정합니다.

Javac은 단일 문자열을 생성 할뿐만 아니라 JVM은 동일한 텍스트를 포함하는 다른 모든 문자열에 하나의 문자열을 사용합니다.

String a = "He" + "llo th"+ "ere";
String b = "Hell" + "o the"+ "re";
String c = "Hello" +" "+"there";
assert a == b; // these are the same String object.
assert a == c; // these are the same String object.

참고 : 다른 항아리의 다른 클래스에있는 경우에도 런타임에 동일한 문자열 객체가되어 다른 컴파일러에 의해 컴파일됩니다.

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