2008-09-26 24 views
186

¿Cuál es la cadena más larga que se puede crear en .NET? Los documentos para la clase String no dicen nada sobre esta cuestión, por lo que puedo ver, por lo que una respuesta autorizada podría requerir algún conocimiento de las partes internas. ¿El cambio máximo en un sistema de 64 bits?¿Cuál es la longitud máxima posible de una cadena .NET?

[Esto se preguntó más por curiosidad que para el uso práctico - no tengo la intención de crear cualquier código que utiliza cadenas gigantescas]

Respuesta

270

El límite teórico puede ser 2147483647, pero el límite práctico está muy lejos de eso. Como ningún objeto 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 asignarlo a un Máquina de 32 bits

Ésta es una de esas situaciones en las que "If you have to ask, you're probably doing something wrong."

+7

Esta es la respuesta correcta. Es más probable que se quede sin memoria antes de poder asignar lo suficiente para agotar la longitud de la cuerda. En un arranque reciente, es posible que pueda obtener una asignación de 2 GB (con 1 millón de caracteres) como se menciona aquí, pero eso es todo. –

+4

Suponiendo que su aseveración de "ningún objeto individual puede ser superior a 2 Gb" es exacta, este ES el límite teórico y el práctico: la restricción en la longitud de cadena sería el tamaño total del objeto, no la capacidad del campo Longitud. – McKenzieG1

+10

Si alguien está interesado en el valor exacto, en mi máquina de 64 bits son 1.073.741.791 (1024 · 1024 · 1024 - 33) caracteres. Ver también [mi pregunta relacionada sobre el tamaño máximo exacto de 'byte []'] (http://stackoverflow.com/q/6616739/41071). – svick

47

Ya que la propiedad Longitud de System.String es un Int32, supongo que la longitud máxima sería 2.147.483.647 caracteres (tamaño máximo Int32). Si permitía más tiempo, no podía verificar la Longitud, ya que eso no funcionaría.

+10

+1 Buena deducción –

+2

@ m.edmondson: Realmente no estoy convencido. Una [matriz] (https://msdn.microsoft.com/en-us/library/system.array%28v=vs.110%29.aspx) para instancias también tiene un 'LongLength' y una secuencia utiliza' long 'como longitud. Aunque es una respuesta válida, no es una forma exacta de medir esto. –

+0

Pero los primeros dos bits se usan para indicación ASCII/no ASCII como [este artículo] (https://www.codeproject.com/Articles/3377/Strings-UNDOCUMENTED) dice, por lo que debería ser 2^30 = 1 073 741 824 – Saito

0

Desde String.length es un número entero (que es un alias para Int32) su tamaño está limitado a caracteres Unicode Int32.MaxValue;)

60

Basado en mi experimento altamente científica y exacta, encabeza a cabo en mi máquina mucho antes de 1,000,000,000 de caracteres (sigo corriendo el código siguiente para obtener una mejor ubicación). ACTUALIZACIÓN: Después de unas horas, me di por vencido. Resultados finales: puede llegar a ser mucho más grande que 100,000,000 caracteres, al instante se le otorga System.OutOfMemoryException a 1,000,000,000 de 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 
} 
+25

La aplicación de una búsqueda binaria aquí probablemente le ayude a encontrar esta respuesta mucho más rápido ... – Mario

+24

+1 para el uso de respuestas controladas por prueba. –

1

200 megas ... momento en el cual su aplicación se detiene virtual, tiene alrededor de un concierto del conjunto de trabajo de la memoria, y la O/s comienza a actuar como si Necesitaremos 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 
+4

No estoy seguro de que el comportamiento que obtendría al crear solo una cadena realmente grande sea el mismo que el que está viendo al asignar un montón y concatenar. – Casey

20

Para cualquiera que venga a este tema tarde, pude ver de que hitscan "probablemente no debería hacer eso" podría llevar a alguien a preguntar lo que deben hacer ...

la clase StringBuilder es a menudo un reemplazo fácil Considere uno de los stream-based classes especialmente si sus datos provienen de un archivo.

El problema con s = s + "cosas" es que tiene que asignar un área completamente nueva para contener los datos y luego copiar todos los datos anteriores más las cosas nuevas - CADA Y CADA BUCLE ITERACIÓN. Entonces, agregar 5 bytes a 1 millón con s = s + "cosas" es extremadamente costoso. Si lo que quieres es escribir 5 bytes hasta el final y continuar con tu programa, entonces debes elegir una clase que deje espacio para crecer.

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

se es golpeado auto-grow by doubling cuando llega el límite de StringBuilder. Entonces verá el dolor de crecimiento una vez al inicio, una vez a 5000 bytes, otra vez a 10000, nuevamente a 20000. Al agregar cadenas se incurrirá en el dolor de cada iteración de bucle.

+4

TAMBIÉN vale la pena señalar que StringBuilder le permite establecer el tamaño inicial. Es útil si sabe que va a utilizar 10.000.000 de entradas antes de tiempo, lo que le permite ignorar parte de la crisis. –

+2

+1 Para ver a través de la pregunta y responder a un buen diseño. Comparativamente, "así de grande es la cuerda antes de que explote", en lugar de "si REALMENTE necesita almacenar mucho texto, use esto ..." – StevoInco

5

Las cadenas no están limitados por el número entero como se cree comúnmente

restricciones de memoria a un lado, las cadenas no puede tener más de 2 (a 1.073.741.824) caracteres, ya que un límite de 2 GB viene impuesta por la Microsoft CLR (Common Language Tiempo de ejecución).

Afortunadamente, esto puede cambiar en el futuro.

0

Tenga en cuenta que BinaryWriter.Write (cadena) escribe la longitud de la cadena como un carácter sin signo (un byte)!

Cuestiones relacionadas