it-swarm.com.de

Was ist die maximal mögliche Länge eines .NET-Strings?

Was ist die längste Zeichenfolge, die in .NET erstellt werden kann? Soweit ich sehen kann, schweigen die Dokumente für die Klasse String zu dieser Frage. Daher erfordert eine maßgebliche Antwort möglicherweise einige Kenntnisse der Interna. Würde sich das Maximum auf einem 64-Bit-System ändern?

[Dies wird eher aus Gründen der Neugier als aus praktischen Gründen gefordert - ich beabsichtige nicht, Code zu erstellen, der gigantische Zeichenfolgen verwendet!]

221
McKenzieG1

Die theoretische Grenze mag bei 2.147.483.647 liegen, aber die praktische Grenze ist weit davon entfernt. Da kein einzelnes Objekt in einem .NET-Programm größer als 2 GB sein darf und der Zeichenfolgentyp Unicode (2 Byte für jedes Zeichen) verwendet, können Sie höchstens 1.073.741.823 Zeichen verwenden, dies können Sie jedoch wahrscheinlich niemals auf einem zuweisen 32-Bit-Maschine.

Dies ist eine der Situationen, in denen "Wenn Sie fragen müssen, machen Sie wahrscheinlich etwas falsch."

318
HitScan

Basierend auf meinem hochgradig wissenschaftlichen und genauen Experiment wird mein Computer deutlich vor 1.000.000.000 Zeichen aufgefüllt. (Ich führe immer noch den folgenden Code aus, um einen genaueren Überblick zu erhalten.).

PDATE: Nach ein paar Stunden habe ich aufgegeben. Endgültige Ergebnisse: Kann viel größer als 100.000.000 Zeichen werden, sobald System.OutOfMemoryException mit 1.000.000.000 Zeichen.

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
}
69
bdukes

Da die Length -Eigenschaft von System.String ist ein Int32, Ich würde vermuten, dass die maximale Länge 2.147.483.647 Zeichen betragen würde (max Int32 Größe). Wenn es länger dauern würde, könnten Sie die Länge nicht überprüfen, da dies fehlschlagen würde.

49
Ryan Farley

Wenn jemand zu spät zu diesem Thema kommt, könnte ich sehen, dass das "Sie sollten das wahrscheinlich nicht tun" von Hitscan dazu führen könnte, dass jemand fragt, was er tun soll ...

Die StringBuilder Klasse ist oft ein einfacher Ersatz. Betrachten Sie eine der stream-basierten Klassen , insbesondere wenn Ihre Daten aus einer Datei stammen.

Das Problem mit s += "stuff" bedeutet, dass ein völlig neuer Bereich für die Daten reserviert werden muss, in den dann alle alten Daten sowie die neuen Daten kopiert werden müssen - JEDE UND JEDE LOOP-ITERATION. Also, füge fünf Bytes zu 1.000.000 hinzu mit s += "stuff" ist extrem teuer. Wenn Sie nur fünf Bytes bis zum Ende schreiben und mit Ihrem Programm fortfahren möchten, müssen Sie eine Klasse auswählen, die Raum für Wachstum lässt:

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

StringBuilder wird automatisch durch Verdoppeln wachsen wenn sein Limit erreicht ist. Sie werden also den Wachstumsschmerz einmal beim Start sehen, einmal bei 5.000 Bytes, noch einmal bei 10.000, noch einmal bei 20.000. Das Anhängen von Zeichenfolgen verursacht bei jeder Schleifeniteration Schmerzen.

27
user922020

Die maximale Länge einer Zeichenfolge auf meinem Computer beträgt 1.073.741.791.

Sie sehen, Strings sind nicht durch ganze Zahlen begrenzt, wie allgemein angenommen wird.

Abgesehen von Speicherbeschränkungen dürfen Strings nicht mehr als 2 haben30 (1,073,741,824) Zeichen, da die Microsoft CLR (Common Language Runtime) eine Beschränkung von 2 GB festlegt. 33 mehr als mein Computer erlaubt.

Hier ist etwas, das du gerne selbst ausprobieren kannst.

Erstellen Sie eine neue C # -Konsolenanwendung in Visual Studio, und kopieren Sie die Hauptmethode, und fügen Sie sie hier ein:

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

}

Meine Ergebnisse waren wie folgt:

Saitentest, von Nicholas John Joseph Taylor

Theoretisch sollte C # eine Zeichenfolge von int.MaxValue unterstützen, aber vorher ist der Speicher voll.

Dies ist ein schneller Test, um die Ergebnisse einzugrenzen und die maximal unterstützte Länge einer Zeichenfolge zu ermitteln.

Der Test beginnt ... jetzt:

an Länge = 1000000000 am 08/05/2019 12:06

Eine Fehlermeldung des Typs 'SystemOutOfMemoryException' wurde angezeigt. am 08/05/2019 12:06. Nach der Dezimierung beträgt der Wert von Increment 100000000.

Eine Fehlermeldung des Typs 'SystemOutOfMemoryException' wurde angezeigt. am 08/05/2019 12:06. Nach der Dezimierung beträgt der Wert von Increment 10000000. s.Length = 1010000000 am 08/05/2019 12:06 s.Length = 1020000000 am 08/05/2019 12:06 s.Length = 1030000000 am 08/05/2019 12 : 06 s.Length = 1040000000 am 08/05/2019 12:06 s.Length = 1050000000 am 08/05/2019 12:06 s.Length = 1060000000 am 08/05/2019 12:06 s.Length = 1070000000 um 08/05/2019 12:06

Eine Fehlermeldung des Typs 'SystemOutOfMemoryException' wurde angezeigt. am 08/05/2019 12:06. Nach der Dezimierung beträgt der Wert von Increment 1000000. s.Length = 1071000000 am 08/05/2019 12:06 s.Length = 1072000000 am 08/05/2019 12:06 s.Length = 1073000000 am 08/05/2019 12 : 06

Eine Fehlermeldung des Typs 'SystemOutOfMemoryException' wurde angezeigt. am 08/05/2019 12:06. Nach der Dezimierung beträgt der Wert von Increment 100000. s.Length = 1073100000 am 08/05/2019 12:06 s.Length = 1073200000 am 08/05/2019 12:06 s.Length = 1073300000 am 08/05/2019 12 : 06 s.Length = 1073400000 am 08/05/2019 12:06 s.Length = 1073500000 am 08/05/2019 12:06 s.Length = 1073600000 am 08/05/2019 12:06 s.Length = 1073700000 um 08/05/2019 12:06

Eine Fehlermeldung des Typs 'SystemOutOfMemoryException' wurde angezeigt. am 08/05/2019 12:06. Nach der Dezimierung beträgt der Wert von Increment 10000. s.Length = 1073710000 am 08/05/2019 12:06 s.Length = 1073720000 am 08/05/2019 12:06 s.Length = 1073730000 am 08/05/2019 12 : 06 s.Length = 1073740000 at 08/05/2019 12:06

Eine Fehlermeldung des Typs 'SystemOutOfMemoryException' wurde angezeigt. am 08/05/2019 12:06. Nach der Dezimierung beträgt der Wert von Increment 1000. s.Length = 1073741000 am 08/05/2019 12:06

Eine Fehlermeldung des Typs 'SystemOutOfMemoryException' wurde angezeigt. am 08/05/2019 12:06. Nach der Dezimierung beträgt der Wert von Increment 100. s.Length = 1073741100 am 08/05/2019 12:06 s.Length = 1073741200 am 08/05/2019 12:06 s.Length = 1073741300 am 08/05/2019 12 : 07 s.Length = 1073741400 am 08/05/2019 12:07 s.Length = 1073741500 am 08/05/2019 12:07 s.Length = 1073741600 am 08/05/2019 12:07 s.Length = 1073741700 um 08/05/2019 12:07

Eine Fehlermeldung des Typs 'SystemOutOfMemoryException' wurde angezeigt. am 08/05/2019 12:07. Nach der Dezimierung beträgt der Wert von Increment 10. s.Length = 1073741710 am 08/05/2019 12:07 s.Length = 1073741720 am 08/05/2019 12:07 s.Length = 1073741730 am 08/05/2019 12 : 07 s.Length = 1073741740 am 08/05/2019 12:07 s.Length = 1073741750 am 08/05/2019 12:07 s.Length = 1073741760 am 08/05/2019 12:07 s.Length = 1073741770 um 08/05/2019 12:07 s.Length = 1073741780 am 08/05/2019 12:07 s.Length = 1073741790 am 08/05/2019 12:07

Eine Fehlermeldung des Typs 'SystemOutOfMemoryException' wurde angezeigt. am 08/05/2019 12:07. Nach der Dezimierung beträgt der Wert von Increment 1. s.Length = 1073741791 at 08/05/2019 12:07

Eine Fehlermeldung des Typs 'SystemOutOfMemoryException' wurde angezeigt. am 08/05/2019 12:07. Nach der Dezimierung ist der Wert von Increment 0. Test abgeschlossen.

Die maximale Länge einer Zeichenfolge beträgt 1073741791.

Drücken Sie eine beliebige Taste, um fortzufahren.

Die maximale Länge einer Saite auf meiner Maschine beträgt 1073741791.

Ich würde es sehr begrüßen, wenn die Leute ihre Ergebnisse als Kommentar unten posten könnten.

Es wird interessant sein zu erfahren, ob die Menschen die gleichen oder unterschiedliche Ergebnisse erzielen.

7

200 Megabyte ... an diesem Punkt kommt Ihre App zum Stillstand, hat ungefähr einen Gigarbeitsspeicher und die O/S beginnen sich so zu verhalten, als müssten Sie neu starten.

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
2
loudej

Schon seit String.Length ist eine Ganzzahl (das ist ein Alias ​​für Int32), seine Größe ist begrenzt auf Int32.MaxValue Unicode-Zeichen. ;-)

1
VVS