programing

의 최대 가능 길이는 얼마입니까?NET 문자열?

mailnote 2023. 5. 16. 22:51
반응형

의 최대 가능 길이는 얼마입니까?NET 문자열?

에서 만들 수 있는 가장 긴 문자열은 무엇입니까?? 의 문서.String수업은 내가 볼 수 있는 한 이 질문에 침묵하기 때문에 권위적인 답변은 내부에 대한 지식을 요구할 수 있습니다.64비트 시스템에서 최대값이 변경됩니까?

[이것은 실용적인 용도보다는 호기심에 더 많은 것을 요구합니다 - 저는 거대한 문자열을 사용하는 코드를 만들 의도는 없습니다!]

이론적 한계는 2,147,483,647일 수 있지만 실제 한계는 그 근처에도 없습니다.에 단일 개체가 없기 때문입니다.NET 프로그램은 2GB 이상이고 문자열 유형은 UTF-16(각 문자에 대해 2바이트)을 사용합니다. 1,073,741,823이 최선이지만 32비트 시스템에서는 할당할 수 없습니다.

이것은 "만약 당신이 물어봐야 한다면, 당신은 아마도 뭔가 잘못하고 있을 것입니다."라고 말하는 상황 중 하나입니다.

저의 고도의 과학적이고 정확한 실험에 따르면, 그것은 1,000,000자보다 훨씬 이전에 제 기계에서 최고입니다. (저는 여전히 더 나은 핀포인트를 얻기 위해 아래의 코드를 실행하고 있습니다.)

업데이트: 몇 시간 후에 저는 포기했습니다.최종 결과: 즉시 제공되는 100,000,000자보다 훨씬 더 크게 이동할 수 있습니다.System.OutOfMemoryException 1,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
}

LengthSystem.String입니다.Int32 최대길 2,147,483,647자)가 될 합니다.Int32더되면 failsize가 되기 수 . 시간이 더 오래 걸리면 실패하기 때문에 Length를 확인할 수 없습니다.

이 주제에 늦게 참여하는 사람이라면, 히트스캔의 "아마도 그렇게 해서는 안 될 것"이 누군가에게 무엇을 해야 하는지 물을 수 있다는 것을 알 수 있었습니다.

StringBuilder 클래스는 종종 쉽게 대체됩니다.특히 데이터가 파일에서 오는 경우 스트림 기반 클래스 중 하나를 고려합니다.

s += "stuff"하고 새하여 1해야 합니다. 따라서 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입니다.

아시다시피 문자열은 일반적으로 믿어지는 정수에 의해 제한되지 않습니다.

메모리 제한은 차치하고 Microsoft CLR(공용 언어 런타임)에 의해 2GB 제한이 적용되므로 문자열은 2자(1,073,741,824)를30 초과할 수 없습니다.내 컴퓨터가 허용한 것보다 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.길이 = 1000000000 at 08/05/2019 12:06

'시스템' 유형의 예외입니다.메모리 부족'예외'가 던져졌습니다.8/05/2019 12:06에.소멸 후 증분 값은 100000000입니다.

'시스템' 유형의 예외입니다.메모리 부족'예외'가 던져졌습니다.8/05/2019 12:06에.소멸 후 증분 값은 10000000.s입니다.길이 = 1010000000 at 08/05/2019 12:06 s.길이 = 1020000000 at 08/05/2019 12:06 s.길이 = 1030000000 at 08/05/2019 12:06 s.길이 = 1040000000 at 08/05/2019 12:06 s.길이 = 1050000000 at 08/05/2019 12:06 s.길이 = 1060000000 at 08/05/2019 12:06 s.길이 = 1070000000 at 08/05/2019 12:06

'시스템' 유형의 예외입니다.메모리 부족'예외'가 던져졌습니다.8/05/2019 12:06에.소멸 후 증분 값은 1000000.s입니다.길이 = 107100000000 at 08/05/2019 12:06 s.길이 = 107200000000 at 08/05/2019 12:06 s.길이 = 1073000000 at 08/05/2019 12:06

'시스템' 유형의 예외입니다.메모리 부족'예외'가 던져졌습니다.8/05/2019 12:06에.소멸 후 증분 값은 100000.s입니다.길이 = 1073100000 at 08/05/2019 12:06 s.길이 = 1073200000 at 08/05/2019 12:06 s.길이 = 1073300000 at 08/05/2019 12:06 s.길이 = 1073400000 at 08/05/2019 12:06 s.길이 = 1073500000 at 08/05/2019 12:06 s.길이 = 1073600000 at 08/05/2019 12:06 s.길이 = 1073700000 at 08/05/2019 12:06

'시스템' 유형의 예외입니다.메모리 부족'예외'가 던져졌습니다.8/05/2019 12:06에.소멸 후 증분 값은 10000.s입니다.길이 = 1073710000 at 08/05/2019 12:06 s.길이 = 1073720000 at 08/05/2019 12:06 s.길이 = 1073730000 at 08/05/2019 12:06 s.길이 = 1073740000 at 08/05/2019 12:06

'시스템' 유형의 예외입니다.메모리 부족'예외'가 던져졌습니다.8/05/2019 12:06에.소멸 후 증분 값은 1000.s입니다.길이 = 1073741000 at 08/05/2019 12:06

'시스템' 유형의 예외입니다.메모리 부족'예외'가 던져졌습니다.8/05/2019 12:06에.소멸 후 증분 값은 100.s입니다.길이 = 1073741100 at 08/05/2019 12:06 s.길이 = 1073741200 at 08/05/2019 12:06 s.길이 = 1073741300 at 08/05/2019 12:07 s.길이 = 1073741400 at 08/05/2019 12:07 s.길이 = 1073741500 at 08/05/2019 12:07 s.길이 = 1073741600 at 08/05/2019 12:07 s.길이 = 1073741700 at 08/05/2019 12:07

'시스템' 유형의 예외입니다.메모리 부족'예외'가 던져졌습니다.8/05/2019 12:07에.소멸 후 증분 값은 10.s입니다.길이 = 1073741710 at 08/05/2019 12:07 s.길이 = 1073741720 at 08/05/2019 12:07 s.길이 = 1073741730 at 08/05/2019 12:07 s.길이 = 1073741740 at 08/05/2019 12:07 s.길이 = 1073741750 at 08/05/2019 12:07 s.길이 = 1073741760 at 08/05/2019 12:07 s.길이 = 1073741770 at 08/05/2019 12:07 s.길이 = 1073741780 at 08/05/2019 12:07 s.길이 = 1073741790 at 08/05/2019 12:07

'시스템' 유형의 예외입니다.메모리 부족'예외'가 던져졌습니다.8/05/2019 12:07에.소멸 후 증분 값은 1.s입니다.길이 = 1073741791 at 08/05/2019 12:07

'시스템' 유형의 예외입니다.메모리 부족'예외'가 던져졌습니다.8/05/2019 12:07에.소멸 후 증분 값은 0입니다.테스트 완료.

문자열의 최대 길이는 1073741791입니다.

계속하려면 아무 키나 누르십시오.

내 기계에 있는 문자열의 최대 길이는 1073741791입니다.

아래 댓글로 결과를 올려주시면 감사하겠습니다.

사람들이 같거나 다른 결과를 얻는다면 배우는 것은 흥미로울 것입니다.

때부터String.Length은 는정에입니다별대칭수한에▁▁alias의 별칭)입니다.Int32), 크기는 다음으로 제한됩니다.Int32.MaxValue유니코드 문자. ;-)

200알...이 시점에서 앱이 가상으로 정지하고, 약 기가 작동하는 세트 메모리가 있고, os가 재부팅이 필요한 것처럼 동작하기 시작합니다.

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

문자열은 RAM 힙에 동적 메모리 크기를 할당합니다.그러나 문자열 주소는 4바이트의 메모리를 차지하는 스택에 저장됩니다.

언급URL : https://stackoverflow.com/questions/140468/what-is-the-maximum-possible-length-of-a-net-string

반응형