.NET 문자열의 가능한 최대 길이는 얼마입니까?
문제
.NET에서 생성 할 수있는 가장 긴 문자열은 무엇입니까? The Docs String
수업은 내가 볼 수있는 한이 질문에 대해 침묵하므로 권위있는 답변에는 내부에 대한 지식이 필요할 수 있습니다. 64 비트 시스템의 최대 변화는?
이것은 실제적인 사용보다 호기심을 더 많이 묻습니다 - 나는 거대한 문자열을 사용하는 코드를 만들려는 의도가 아닙니다!
해결책
이론적 한계는 2,147,483,647 일 수 있지만 실질적인 한계는 그 근처에 없습니다. .NET 프로그램의 단일 객체는 2GB 이상이고 문자열 유형은 유니 코드 (각 문자마다 2 바이트)를 사용하기 때문에 최선을 다하면 1,073,741,823이지만이를 할당 할 수는 없습니다. 32 비트 기계.
이것은 그 상황 중 하나입니다 "물어봐야한다면 아마도 뭔가 잘못하고있을 것입니다."
다른 팁
과학적이고 정확한 실험을 바탕으로 1,000,000,000 자 전에 내 컴퓨터에서 잘 어울립니다. (더 나은 정확도를 얻기 위해 아래 코드를 여전히 실행하고 있습니다).
업데이트:몇 시간 후, 나는 포기했다. 최종 결과 : 즉시 10 만 명의 문자보다 훨씬 클 수 있습니다. System.OutOfMemoryException
1,000,000,000 자.
using System;
using System.Collections.Generic;
public class MyClass
{
public static void Main()
{
int i = 100000000;
try
{
for (i = i; i <= int.MaxValue; i += 5000)
{
string value = new string('x', i);
//WL(i);
}
}
catch (Exception exc)
{
WL(i);
WL(exc);
}
WL(i);
RL();
}
#region Helper methods
private static void WL(object text, params object[] args)
{
Console.WriteLine(text.ToString(), args);
}
private static void RL()
{
Console.ReadLine();
}
private static void Break()
{
System.Diagnostics.Debugger.Break();
}
#endregion
}
이후 Length
의 자산 System.String
이다 Int32
, 나는 최대 길이가 2,147,483,647 숯일 것이라고 생각합니다 (최대 Int32
크기). 더 오래 허용되면 길이가 실패하기 때문에 길이를 확인할 수 없었습니다.
늦게이 주제에 오는 사람에게는 Hitscan의 "당신은 아마 그렇게하지 말아야 할 것"이라는 것을 알 수있었습니다. 누군가가해야 할 일을 물어볼 수 있습니다 ...
그만큼 StringBuilder 수업은 종종 쉬운 교체입니다. 하나를 고려하십시오 스트림 기반 클래스 특히 데이터가 파일에서 나오는 경우.
문제 s += "stuff"
데이터를 보유한 다음 모든 오래된 데이터를 새로운 내용으로 복사하기 위해 완전히 새로운 영역을 할당해야한다는 것입니다. 각각의 루프 반복. 따라서 5 바이트를 1,000,000으로 추가합니다 s += "stuff"
매우 비용이 많이 듭니다. 당신이 원하는 것이 끝까지 5 바이트를 작성하고 프로그램을 진행한다면, 성장의 여지를 남길 수있는 수업을 선택해야합니다.
StringBuilder sb = new StringBuilder(5000);
for (; ; )
{
sb.Append("stuff");
}
StringBuilder
~ 할 것이다 배가되어 자동 성장 제한이 맞으면 따라서 처음에는 5,000 바이트에서 한 번, 다시 10,000에서 다시 20,000에서 성장 통증을 볼 수 있습니다. 추가 문자열은 모든 루프 반복의 통증이 발생합니다.
문자열의 최대 길이 내 기계에 ~이다 1,073,741,791.
알다시피, 문자열은 일반적으로 믿는대로 정수에 의해 제한되지 않습니다.
메모리 제한을 제외하고, 문자열은 2 이상을 가질 수 없습니다.30 (1,073,741,824) 문자, 2GB 제한은 Microsoft CLR (공통 언어 런타임)에 의해 부과되므로. 내 컴퓨터가 허용하는 것보다 33.
자, 여기 당신이 스스로 시도해 보시는 것이 있습니다.
Visual Studio에서 새 C# 콘솔 앱을 작성한 다음 여기에서 기본 방법을 복사/붙여 넣으십시오.
static void Main(string[] args)
{
Console.WriteLine("String test, by Nicholas John Joseph Taylor");
Console.WriteLine("\nTheoretically, C# should support a string of int.MaxValue, but we run out of memory before then.");
Console.WriteLine("\nThis is a quickish test to narrow down results to find the max supported length of a string.");
Console.WriteLine("\nThe test starts ...now:\n");
int Length = 0;
string s = "";
int Increment = 1000000000; // We know that s string with the length of 1000000000 causes an out of memory exception.
LoopPoint:
// Make a string appendage the length of the value of Increment
StringBuilder StringAppendage = new StringBuilder();
for (int CharacterPosition = 0; CharacterPosition < Increment; CharacterPosition++)
{
StringAppendage.Append("0");
}
// Repeatedly append string appendage until an out of memory exception is thrown.
try
{
if (Increment > 0)
while (Length < int.MaxValue)
{
Length += Increment;
s += StringAppendage.ToString(); // Append string appendage the length of the value of Increment
Console.WriteLine("s.Length = " + s.Length + " at " + DateTime.Now.ToString("dd/MM/yyyy HH:mm"));
}
}
catch (OutOfMemoryException ex) // Note: Any other exception will crash the program.
{
Console.WriteLine("\n" + ex.Message + " at " + DateTime.Now.ToString("dd/MM/yyyy HH:mm") + ".");
Length -= Increment;
Increment /= 10;
Console.WriteLine("After decimation, the value of Increment is " + Increment + ".");
}
catch (Exception ex2)
{
Console.WriteLine("\n" + ex2.Message + " at " + DateTime.Now.ToString("dd/MM/yyyy HH:mm") + ".");
Console.WriteLine("Press a key to continue...");
Console.ReadKey();
}
if (Increment > 0)
{
goto LoopPoint;
}
Console.WriteLine("Test complete.");
Console.WriteLine("\nThe max length of a string is " + s.Length + ".");
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
내 결과는 다음과 같습니다.
Nicholas John Joseph Taylor의 현악 테스트
이론적으로 C#은 int.maxvalue의 문자열을 지원해야하지만 그 전에는 메모리가 부족합니다.
이것은 최대 지원되는 스트링 길이를 찾기 위해 결과를 좁히기위한 빠른 테스트입니다.
테스트가 시작됩니다 ... 지금 :
S.length = 10000000000 at 08/05/2019 12:06
'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:06. 소멸 후 증분 값은 1000000000입니다.
'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:06. 소멸 후 증분 값은 100000000입니다. S.length = 1010000000 at 08/05/2019 12:06 S.Length = 1020000000 at 08/05/2019 12:06 S.Length = 1030000000 at 08/05/2019 12 : 06 S.length = 1040000000 at 08/05/2019 12:06 S.length = 1050000000 at 08/05/2019 12:06 S.length = 1060000000 at 08/05/2019 12:06 S.length = 1070000000 at at 08/05/2019 12:06
'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:06. 소멸 후 증분 값은 10000000입니다. S.length = 1071000000 at 08/05/2019 12:06 S.Length = 1072000000 at 08/05/2019 12:06 S.Length = 1073000000 at 08/05/2019 12 : 06
'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:06. 소멸 후 증분 값은 100000입니다. S.length = 1073100000 at 08/05/2019 12:06 S.Length = 1073200000 at 08/05/2019 12:06 S.Length = 1073300000 at 08/05/2019 12 : 06 S.length = 1073400000 at 08/05/2019 12:06 S.length = 1073500000 at 08/05/2019 12:06 S.length = 1073600000 at 08/05/2019 12:06 S.length = 1073700000 at at at 08/05/2019 12:06
'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:06. 소멸 후 증분 값은 10000입니다. S.length = 1073710000 at 08/05/2019 12:06 S.Length = 1073720000 at 08/05/2019 12:06 S.Length = 1073730000 at 08/05/2019 12 : 06 S.length = 1073740000 at 08/05/2019 12:06
'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:06. 소멸 후 증분 값은 1000입니다. S.length = 1073741000 at 08/05/2019 12:06
'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:06. 소멸 후 증분 값은 100입니다. S.length = 1073741100 at 08/05/2019 12:06 S.Length = 1073741200 at 08/05/2019 12:06 S.Length = 1073741300 at 08/05/2019 12 : 07 S.length = 1073741400 at 08/05/2019 12:07 S.Length = 1073741500 at 08/05/2019 12:07 S.length = 1073741600 at 08/05/2019 12:07 S.length = 1073741700 at at 08/05/2019 12:07
'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:07. 소멸 후 증분 값은 10입니다. S.length = 1073741710 at 08/05/2019 12:07 S.Length = 1073741720 at 08/05/2019 12:07 S.Length = 1073741730 at 08/05/2019 12 : 07 S.length = 1073741740 at 08/05/2019 12:07 S.Length = 1073741750 at 08/05/2019 12:07 S.length = 1073741760 at 08/05/2019 12:07 S.length = 1073741770 at 08/05/2019 12:07 S.length = 1073741780 at 08/05/2019 12:07 S.length = 1073741790 at 08/05/2019 12:07
'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:07. 소멸 후, 증분 값은 1입니다. S.length = 1073741791 at 08/05/2019 12:07
'System.outofMemoryException'유형을 제외하고는 발생했습니다. 08/05/2019 12:07. 소멸 후, 증분 값은 0입니다. 테스트 완료.
문자열의 최대 길이는 1073741791입니다.
계속하려면 키를 누르십시오.
내 컴퓨터의 문자열의 최대 길이는 1073741791입니다.
사람들이 결과를 아래에 의견으로 게시 할 수 있다면 대단히 감사합니다.
사람들이 동일하거나 다른 결과를 얻는 지 배우는 것이 흥미로울 것입니다.
200 Megs ... 그 시점에서 앱은 가상 중단으로 갈고, 공연 작업 세트 메모리가 있으며 O/S는 재부팅 해야하는 것처럼 행동하기 시작합니다.
static void Main(string[] args)
{
string s = "hello world";
for(;;)
{
s = s + s.Substring(0, s.Length/10);
Console.WriteLine(s.Length);
}
}
12
13
14
15
16
17
18
...
158905664
174796230
192275853
211503438
부터 String.Length
정수입니다 (그것은 별명입니다 Int32
), 크기는로 제한됩니다 Int32.MaxValue
유니 코드 문자. ;-)