Pergunta

O que é a cadeia mais longa que pode ser criado em .NET? A documentação para a classe String estão em silêncio sobre esta questão, tanto quanto eu posso ver, portanto, uma resposta autoritária pode exigir algum conhecimento de internos. Será que a variação máxima em um sistema de 64 bits?

[Esta é perguntado mais por curiosidade do que para uso prático - Não tenho a intenção de criar qualquer código que utiliza cordas gigantescas]

Foi útil?

Solução

O limite teórico pode ser 2,147,483,647, mas o limite prático é nem perto disso. Uma vez que nenhum único objeto em um programa de .NET pode ser mais de 2 GB eo tipo string usa Unicode (2 bytes para cada personagem), o melhor que você poderia fazer é 1073741823, mas você não é provável que você nunca será capaz de alocar que em um 32-bit máquina.

Esta é uma daquelas situações em que "Se você tem que perguntar, você 'provavelmente está fazendo algo errado. "

Outras dicas

Com base na minha experiência altamente científica e precisos, que encabeça fora na minha máquina bem antes de 1.000.000.000 caracteres. (Eu ainda estou correndo o código abaixo para obter um pontinho melhor).

UPDATE: Depois de algumas horas, eu desisti. Os resultados finais:. Pode ir muito maior do que 100.000.000 personagens, dada instantaneamente System.OutOfMemoryException em 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
}

Uma vez que a propriedade Length de System.String é um Int32, eu acho que se o comprimento máximo seria 2,147,483,647 caracteres (tamanho máximo Int32). Se permitido por muito tempo você não poderia verificar o comprimento desde que falharia.

Para qualquer um que vem a este tópico tarde, eu podia ver que de hitscan "você provavelmente não deveria fazer isso" pode causar alguém para perguntar o que devem fazer ...

O StringBuilder classe é muitas vezes uma substituição fácil. Considere um dos aulas baseadas em fluxo especialmente, se os seus dados é proveniente de um arquivo.

O problema com s += "stuff" é que ele tem para alocar uma área completamente nova para armazenar os dados e, em seguida, copiar todos os dados antigos para que mais o novo material - CADA iteração do loop. Assim, a adição de cinco bytes para 1.000.000 com s += "stuff" é extremamente caro. Se o que você quer é apenas escrever cinco bytes para o final e prosseguir com o seu programa, você tem que escolher uma classe que deixa algum espaço para o crescimento:

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

StringBuilder vai auto-grow dobrando quando é limite é atingido. Então, você vai ver a dor do crescimento uma vez no início, uma vez em 5.000 bytes, novamente a 10.000, mais uma vez em 20.000. Anexando cordas terã a dor a cada iteração do loop.

O comprimento máximo de uma string na minha máquina é 1073741791 .

Você vê, cordas não são limitados por inteiro como normalmente se pensa.

restrições de memória de lado, Cordas não pode ter mais de 2 30 ( 1073741824 ) caracteres, uma vez que um limite de 2GB é imposta pela Microsoft CLR (Common Language Runtime). 33 mais do que o meu computador permitido.

Agora, está aqui algo que você está convidado a experimentar a si mesmo.

Criar um novo C # consola de aplicação no Visual Studio e, em seguida, copiar / colar o principal método aqui:

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

}

Meus resultados foram os seguintes:

teste String, por Nicholas John Joseph Taylor

Teoricamente, C # devem apoiar uma série de int.MaxValue, mas corremos sem memória antes disso.

Este é um teste quickish para reduzir os resultados para encontrar o máximo comprimento apoiado de uma string.

As partidas de teste ... agora:

s.length = 1000000000 em 2019/08/05 00:06

exceção do tipo 'System.OutOfMemoryException' foi lançada. em 2019/08/05 00:06. Depois de dizimação, o valor de incremento é 100000000.

exceção do tipo 'System.OutOfMemoryException' foi lançada. em 2019/08/05 00:06. Depois de dizimação, o valor de incremento é 10000000. s.length = 1010000000 em 2019/08/05 12:06 s.length = 1020000000 em 2019/08/05 12:06 s.length = 1030000000 em 2019/08/05 12:06 s.length = 1040000000 em 2019/08/05 12:06 s.length = 1050000000 em 2019/08/05 12:06 s.length = 1060000000 em 2019/08/05 00:06 s.length = 1070000000 em 2019/08/05 00:06

exceção do tipo 'System.OutOfMemoryException' foi lançada. em 2019/08/05 00:06. Depois de dizimação, o valor do incremento é 1000000. s.length = 1071000000 em 2019/08/05 12:06 s.length = 1072000000 em 2019/08/05 12:06 s.length = 1,073 bilhões em 2019/08/05 00:06

exceção do tipo 'System.OutOfMemoryException' foi lançada. em 2019/08/05 00:06. Depois de dizimação, o valor do incremento é 100000. s.length = 1073100000 em 2019/08/05 12:06 s.length = 1073200000 em 2019/08/05 12:06 s.length = 1073300000 em 2019/08/05 12:06 s.length = 1073400000 em 2019/08/05 12:06 s.length = 1073500000 em 2019/08/05 12:06 s.length = 1073600000 em 2019/08/05 12:06 s.length = 1073700000 em 2019/08/05 00:06

exceção do tipo 'System.OutOfMemoryException' foi lançada. em 2019/08/05 00:06. Depois de dizimação, o valor do incremento é 10000. s.length = 1073710000 em 2019/08/05 12:06 s.length = 1073720000 em 2019/08/05 12:06 s.length = 1073730000 em 2019/08/05 12:06 s.length = 1073740000 em 2019/08/05 00:06

exceção do tipo 'System.OutOfMemoryException' foi lançada. em 2019/08/05 00:06. Depois de dizimação, o valor de incremento é 1,000. s.length = 1073741000 em 2019/08/05 00:06

exceção do tipo 'System.OutOfMemoryException' foi lançada. em 2019/08/05 00:06. Depois de dizimação, o valor de incremento é 100. s.length = 1073741100 em 2019/08/05 12:06 s.length = 1073741200 em 2019/08/05 00:06 s.length = 1073741300 em 2019/08/05 12:07 s.length = 1073741400 em 2019/08/05 00:07 s.length = 1073741500 em 2019/08/05 00:07 s.length = 1073741600 em 2019/08/05 12:07 s.length = 1073741700 em 2019/08/05 00:07

exceção do tipo 'System.OutOfMemoryException' foi lançada. em 2019/08/05 00:07. Depois de dizimação, o valor de incremento é 10. s.length = 1073741710 em 2019/08/05 12:07 s.length = 1073741720 em 2019/08/05 00:07 s.length = 1073741730 em 2019/08/05 12:07 s.length = 1073741740 em 2019/08/05 00:07 s.length = 1073741750 em 2019/08/05 00:07 s.length = 1073741760 em 2019/08/05 12:07 s.length = 1073741770 em 2019/08/05 12:07 s.length = 1073741780 em 2019/08/05 12:07 s.length = 1073741790 em 2019/08/05 00:07

exceção do tipo 'System.OutOfMemoryException' foi lançada. em 2019/08/050:07. Depois de dizimação, o valor de incremento é 1. s.length = 1073741791 em 2019/08/05 00:07

exceção do tipo 'System.OutOfMemoryException' foi lançada. em 2019/08/05 00:07. Depois de dizimação, o valor de incremento é 0. Teste completa.

O comprimento máximo de uma string é 1073741791.

Pressione qualquer tecla para continuar.

O comprimento máximo de uma corda na minha máquina é 1073741791.

Eu apreciaria muito se as pessoas poderiam postar seus resultados como um comentário abaixo.

Será interessante saber se as pessoas obter os mesmos ou diferentes resultados.

200 megas ... altura em que os seus grinds de aplicativos a uma parada virtual, tem cerca de uma memória conjunto de trabalho show, e o / s começa a agir como você precisará 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

Desde String.Length é um inteiro (que é um alias para Int32), seu tamanho é limitado a personagens Int32.MaxValue unicode. ; -)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top