Domanda

Qual è la stringa più lunga che può essere creata in .NET? I documenti per la classe String sono in silenzio su questa domanda per quanto posso vedere, quindi una risposta autorevole potrebbe richiedere una certa conoscenza degli interni. Il massimo cambiamento su un sistema a 64 bit?

[Questo è richiesto più dalla curiosità che dall'uso pratico - Non intendo creare alcun codice che usi stringhe gigantesche!]

È stato utile?

Soluzione

Il limite teorico può essere 2.147.483.647, ma il limite pratico non è affatto vicino a quello. Dato che nessun oggetto singolo in un programma .NET può superare i 2 GB e il tipo di stringa utilizza Unicode (2 byte per ogni carattere), il meglio che puoi fare è 1.073.741.823, ma probabilmente non sarai mai in grado di allocarlo su un Macchina a 32 bit.

Questa è una di quelle situazioni in cui " Se devi chiedere, probabilmente stai facendo qualcosa di sbagliato. "

Altri suggerimenti

Basato sul mio esperimento altamente scientifico e accurato, supera la mia macchina ben prima di 1.000.000.000 di caratteri. (Sto ancora eseguendo il codice qui sotto per ottenere un punto più preciso).

UPDATE: Dopo poche ore, ho rinunciato. Risultati finali: può andare molto più grande di 100.000.000 di caratteri, dato immediatamente System.OutOfMemoryException a 1.000.000.000 di caratteri.

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
}

Poiché la proprietà Lunghezza di System.String è un Int32 , immagino che la lunghezza massima sarebbe di 2.147.483.647 caratteri (max Int32 ). Se fosse consentito più a lungo, non è possibile controllare la lunghezza poiché ciò non riuscirebbe.

Per chiunque venisse in ritardo su questo argomento, potrei vedere che hitcan's probabilmente non dovresti farlo " potrebbe indurre qualcuno a chiedere cosa dovrebbe fare & # 8230;

StringBuilder class è spesso un facile rimpiazzo. Prendi in considerazione una delle classi basate su stream in particolare, se i tuoi dati provengono da un file.

Il problema con s + = " stuff " è che deve allocare un'area completamente nuova per contenere i dati e quindi copiare tutti i vecchi dati su di essa più le nuove cose - EACH E OGNI ITERAZIONE A LOOP. Pertanto, aggiungere cinque byte a 1.000.000 con s + = " stuff " è estremamente costoso. Se quello che vuoi è solo scrivere cinque byte fino alla fine e procedere con il tuo programma, devi scegliere una classe che lasci spazio alla crescita:

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

StringBuilder sarà cresce automaticamente raddoppiando quando viene raggiunto il limite. Quindi, vedrai il dolore della crescita una volta all'inizio, una volta a 5.000 byte, di nuovo a 10.000, di nuovo a 20.000. L'aggiunta di stringhe comporterà il dolore ad ogni iterazione di loop.

La lunghezza massima di una stringa sulla mia macchina è 1.073.741.791 .

Vedete, le stringhe non sono limitate dall'intero come si crede comunemente.

Limitazioni della memoria a parte, le stringhe non possono contenere più di 2 30 ( 1.073.741.824 ), poiché un limite di 2 GB è imposto dal CLR Microsoft (Common Language Runtime). 33 in più di quanto consentito dal mio computer.

Ora, ecco qualcosa che puoi provare tu stesso.

Crea una nuova app console C # in Visual Studio e copia / incolla qui il metodo principale:

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

}

I miei risultati sono stati i seguenti:

  

Test delle stringhe, di Nicholas John Joseph Taylor

     

Teoricamente, C # dovrebbe supportare una stringa di int.MaxValue, ma eseguiamo   memoria esaurita prima di allora.

     

Questo è un test rapido per restringere i risultati per trovare il massimo   lunghezza supportata di una stringa.

     

Il test inizia ... ora:

     

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

     

È stata generata un'eccezione del tipo "System.OutOfMemoryException". a   08/05/2019 12:06. Dopo la decimazione, il valore di Incremento è   100000000.

     

È stata generata un'eccezione del tipo "System.OutOfMemoryException". a   08/05/2019 12:06. Dopo la decimazione, il valore di Incremento è   10000000. 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   a 08/05/2019 12:06 s.Lunghezza = 1060000000 a 08/05/2019 12:06 s.Lunghezza   = 1070000000 all'08 / 05/2019 12:06

     

È stata generata un'eccezione del tipo "System.OutOfMemoryException". a   08/05/2019 12:06. Dopo la decimazione, il valore di Incremento è 1000000.   lunghezza = 1071000000 al 08/05/2019 12:06 lunghezza = 1072000000 a   08/05/2019 12:06 s.Lunghezza = 1073000000 alle 08/05/2019 12:06

     

È stata generata un'eccezione del tipo "System.OutOfMemoryException". a   08/05/2019 12:06. Dopo la decimazione, il valore di Incremento è 100000.   Lunghezza s = 1073100000 a 08/05/2019 12:06 Lunghezza s = 1073200000 a   08/05/2019 12:06 s.Length = 1073300000 at 08/05/2019 12:06 s.Length =   1073400000 al 08/05/2019 12:06 s.Lunghezza = 1073500000 al 08/05/2019   12:06 s.Length = 1073600000 at 08/05/2019 12:06 s.Length = 1073700000   al 08/05/2019 12:06

     

È stata generata un'eccezione del tipo "System.OutOfMemoryException". a   08/05/2019 12:06. Dopo la decimazione, il valore di Incremento è 10000.   lunghezza = 1073710000 al 08/05/2019 12:06 lunghezza = 1073720000 a   08/05/2019 12:06 s.Length = 1073730000 at 08/05/2019 12:06 s.Length =   1073740000 all'08 / 05/2019 12:06

     

È stata generata un'eccezione del tipo "System.OutOfMemoryException". a   08/05/2019 12:06. Dopo la decimazione, il valore di Incremento è 1000.   s.Length = 1073741000 at 08/05/2019 12:06

     

È stata generata un'eccezione del tipo "System.OutOfMemoryException". a   08/05/2019 12:06. Dopo la decimazione, il valore di Incremento è 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 al 08/05/2019 12:07 s.Lunghezza = 1073741500 al 08/05/2019   12:07 s.Lunghezza = 1073741600 al 08/05/2019 12:07 s.Lunghezza = 1073741700   al 08/05/2019 12:07

     

È stata generata un'eccezione del tipo "System.OutOfMemoryException". a   08/05/2019 12:07. Dopo la decimazione, il valore di Incremento è 10.   lunghezza = 1073741710 al 08/05/2019 12:07 lunghezza = 1073741720 a   08/05/2019 12:07 s.Lunghezza = 1073741730 a 08/05/2019 12:07 s.Lunghezza =   1073741740 al 08/05/2019 12:07 s.Lunghezza = 1073741750 al 08/05/2019   12:07 s.Lunghezza = 1073741760 al 08/05/2019 12:07 s.Lunghezza = 1073741770   a 08/05/2019 12:07 s.Lunghezza = 1073741780 a 08/05/2019 12:07 s.Lunghezza   = 1073741790 al 08/05/2019 12:07

     

È stata generata un'eccezione del tipo "System.OutOfMemoryException". a   08/05/2019 12:07. Dopo la decimazione, il valore di Incremento è 1.   lunghezza = 1073741791 al 08/05/2019 12:07

     

È stata generata un'eccezione del tipo "System.OutOfMemoryException". a   08/05/2019 12:07. Dopo la decimazione, il valore di Incremento è 0. Test   completa.

     

La lunghezza massima di una stringa è 1073741791.

     

Premi un tasto qualsiasi per continuare.

La lunghezza massima di una stringa sulla mia macchina è 1073741791.

Gradirei molto se le persone potessero pubblicare i loro risultati come un commento qui sotto.

Sarà interessante sapere se le persone ottengono risultati uguali o diversi.

200 mega ... a quel punto la tua app si interrompe in modo virtuale, ha circa un concerto funzionante e la memoria inizia a funzionare come se dovessi riavviare.

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

Poiché String.Length è un numero intero (ovvero un alias per Int32 ), la sua dimensione è limitata ai caratteri unicode Int32.MaxValue . ; -)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top