Pregunta

¿Cuál es la cadena más larga que se puede crear en .NET? Los documentos para la clase String guardan silencio sobre esta pregunta, por lo que puedo ver, por lo que una respuesta autorizada puede requerir un poco de conocimiento de las partes internas. ¿Cambiaría el máximo en un sistema de 64 bits?

[Esto se pide más por curiosidad que por uso práctico: ¡no tengo la intención de crear ningún código que use cadenas gigantescas!]

¿Fue útil?

Solución

El límite teórico puede ser 2,147,483,647, pero el límite práctico no está cerca de eso. Dado que ningún objeto individual en un programa .NET puede tener más de 2 GB y el tipo de cadena usa Unicode (2 bytes para cada carácter), lo mejor que puede hacer es 1,073,741,823, pero es probable que nunca pueda asignar eso en un Máquina de 32 bits.

Esta es una de esas situaciones donde " Si tiene que preguntar, probablemente estás haciendo algo mal. "

Otros consejos

Basado en mi experimento altamente científico y preciso, supera mi máquina mucho antes de 1,000,000,000 de caracteres. (Todavía estoy ejecutando el código a continuación para obtener una mejor identificación).

ACTUALIZACIÓN: Después de unas horas, me di por vencido. Resultados finales: puede ir mucho más grande que 100,000,000 caracteres, dado instantáneamente System.OutOfMemoryException en 1,000,000,000 caracteres.

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
}

Dado que la propiedad Length de System.String es un Int32 , supongo que la longitud máxima sería 2.147.483.647 caracteres (máx. tamaño Int32 ). Si permitiera más tiempo, no podría verificar la longitud ya que eso fallaría.

Para cualquiera que llegue tarde a este tema, podría ver que hitscan '' probablemente no deberías hacer eso '' puede hacer que alguien pregunte qué debe hacer & # 8230;

El StringBuilder clase es a menudo un reemplazo fácil. Considere una de las clases basadas en transmisión especialmente, si sus datos provienen de un archivo.

El problema con s + = " stuff " es que tiene que asignar un área completamente nueva para contener los datos y luego copiar todos los datos antiguos más los nuevos - CADA UNO Y CADA ITERACIÓN DE LAZO. Entonces, agregar cinco bytes a 1,000,000 con s + = " stuff " es extremadamente costoso. Si lo que desea es escribir cinco bytes hasta el final y continuar con su programa, debe elegir una clase que deje espacio para crecer:

StringBuilder sb = new StringBuilder(5000);
for (; ; )
    {
        sb.Append("stuff");
    }

StringBuilder crecer automáticamente duplicando cuando se alcanza su límite. Entonces, verá el dolor de crecimiento una vez al comienzo, una vez a 5,000 bytes, nuevamente a 10,000, nuevamente a 20,000. Añadir cadenas provocará el dolor en cada iteración del bucle.

La longitud máxima de una cadena en mi máquina es 1,073,741,791 .

Verá, las cadenas no están limitadas por un número entero como se cree comúnmente.

Dejando a un lado las restricciones de memoria, las cadenas no pueden tener más de 2 30 ( 1,073,741,824 ) caracteres, ya que Microsoft CLR (Common Language Runtime) impone un límite de 2GB. 33 más de lo que permitía mi computadora.

Ahora, aquí hay algo que puede probar usted mismo.

Cree una nueva aplicación de consola C # en Visual Studio y luego copie / pegue el método principal aquí:

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();

}

Mis resultados fueron los siguientes:

  

Prueba de cuerda, por Nicholas John Joseph Taylor

     

Teóricamente, C # debería admitir una cadena de int.MaxValue, pero ejecutamos   sin memoria antes de eso.

     

Esta es una prueba rápida para reducir los resultados para encontrar el máximo   longitud admitida de una cadena.

     

La prueba comienza ... ahora:

     

s.Length = 1000000000 a 05/08/2019 12:06

     

Se produjo una excepción del tipo 'System.OutOfMemoryException'. a   05/08/2019 12:06. Después de la aniquilación, el valor de Incremento es   100000000.

     

Se produjo una excepción del tipo 'System.OutOfMemoryException'. a   05/08/2019 12:06. Después de la aniquilación, el valor de Incremento es   10000000. s.Longitud = 1010000000 a 05/08/2019 12:06 s.Longitud = 1020000000 a 08/05/2019 12:06 s.Longitud = 1030000000 a 05/08/2019   12:06 s.Longitud = 1040000000 a 05/08/2019 12:06 s.Longitud = 1050000000   a 08/05/2019 12:06 s.Longitud = 1060000000 a 08/05/2019 12:06 s.Longitud   = 1070000000 el 05/08/2019 12:06

     

Se produjo una excepción del tipo 'System.OutOfMemoryException'. a   05/08/2019 12:06. Después de la aniquilación, el valor de Incremento es 1000000.   s.Longitud = 1071000000 en 08/05/2019 12:06 s.Longitud = 1072000000 en   05/08/2019 12:06 s.Longitud = 1073000000 a 05/08/2019 12:06

     

Se produjo una excepción del tipo 'System.OutOfMemoryException'. a   05/08/2019 12:06. Después de la aniquilación, el valor de Incremento es 100000.   s.Length = 1073100000 en 08/05/2019 12:06 s.Length = 1073200000 en   05/08/2019 12:06 s.Longitud = 1073300000 a 08/05/2019 12:06 s.Longitud =   1073400000 el 05/08/2019 12:06 s.Longitud = 1073500000 el 05/08/2019   12:06 s.Longitud = 1073600000 a 05/08/2019 12:06 s.Longitud = 1073700000   al 08/05/2019 12:06

     

Se produjo una excepción del tipo 'System.OutOfMemoryException'. a   05/08/2019 12:06. Después de la destrucción, el valor de Incremento es 10000.   s.Length = 1073710000 a 08/05/2019 12:06 s.Length = 1073720000 a   05/08/2019 12:06 s.Longitud = 1073730000 a 08/05/2019 12:06 s.Longitud =   1073740000 el 05/08/2019 12:06

     

Se produjo una excepción del tipo 'System.OutOfMemoryException'. a   05/08/2019 12:06. Después de la aniquilación, el valor de Incremento es 1000.   s.Longitud = 1073741000 el 05/08/2019 12:06

     

Se produjo una excepción del tipo 'System.OutOfMemoryException'. a   05/08/2019 12:06. Después de la destrucción, el valor de Incremento es 100.   s.Length = 1073741100 en 08/05/2019 12:06 s.Length = 1073741200 en   05/08/2019 12:06 s.Longitud = 1073741300 a 08/05/2019 12:07 s.Longitud =   1073741400 el 05/08/2019 12:07 s.Longitud = 1073741500 el 05/08/2019   12:07 s.Longitud = 1073741600 a 08/05/2019 12:07 s.Longitud = 1073741700   al 08/05/2019 12:07

     

Se produjo una excepción del tipo 'System.OutOfMemoryException'. a   05/08/2019 12:07. Después de la aniquilación, el valor de Incremento es 10.   s.Length = 1073741710 en 08/05/2019 12:07 s.Length = 1073741720 en   05/08/2019 12:07 s.Longitud = 1073741730 a 08/05/2019 12:07 s.Longitud =   1073741740 el 05/08/2019 12:07 s.Longitud = 1073741750 el 05/08/2019   12:07 s.Longitud = 1073741760 a 08/05/2019 12:07 s.Longitud = 1073741770   a 08/05/2019 12:07 s.Longitud = 1073741780 a 08/05/2019 12:07 s.Longitud   = 1073741790 el 05/08/2019 12:07

     

Se produjo una excepción del tipo 'System.OutOfMemoryException'. a   05/08/2019 12:07. Después de la destrucción, el valor de Incremento es 1.   s.Longitud = 1073741791 al 08/05/2019 12:07

     

Se produjo una excepción del tipo 'System.OutOfMemoryException'. a   05/08/2019 12:07. Después de la destrucción, el valor de Incremento es 0. Prueba   completo.

     

La longitud máxima de una cadena es 1073741791.

     

Presione cualquier tecla para continuar.

La longitud máxima de una cadena en mi máquina es 1073741791.

Agradecería mucho si las personas pudieran publicar sus resultados como un comentario a continuación.

Será interesante saber si las personas obtienen los mismos o diferentes resultados.

200 megas ... en ese momento, su aplicación se detiene virtualmente, tiene una memoria de conjunto de trabajo y la o / s comienza a actuar como si necesitara reiniciar.

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

Dado que String.Length es un número entero (que es un alias para Int32 ), su tamaño está limitado a caracteres unicode Int32.MaxValue . ;-)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top