Какова максимально возможная длина строки .NET? - PullRequest
214 голосов
/ 26 сентября 2008

Какую самую длинную строку можно создать в .NET? Насколько мне известно, в документах для класса String об этом вопросе ничего не говорится, поэтому для авторитетного ответа могут потребоваться некоторые знания внутренних органов. Изменится ли максимум в 64-битной системе?

[Это спрашивает больше о любопытстве, чем о практическом использовании - я не собираюсь создавать код, который использует гигантские строки!]

Ответы [ 7 ]

312 голосов
/ 26 сентября 2008

Теоретический предел может составлять 2 147 483 647, но практический предел далеко не таков. Поскольку ни один объект в .NET-программе не может быть больше 2 ГБ, а строковый тип использует Unicode (2 байта на каждый символ), лучшее, что вы можете сделать, это 1 073 741 823, но вы вряд ли когда-либо сможете выделить его на 32-битный компьютер.

Это одна из тех ситуаций, когда «Если вам нужно спросить, вы, вероятно, делаете что-то не так».

68 голосов
/ 26 сентября 2008

Исходя из моего очень научного и точного эксперимента, он превосходит мою машину задолго до 1 000 000 000 символов. (Я все еще использую приведенный ниже код, чтобы получить лучшее определение).

UPDATE: Через несколько часов я сдался. Окончательные результаты: может превышать 100 000 000 символов, мгновенно получая System.OutOfMemoryException при 1 000 000 000 символов.

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
}
49 голосов
/ 26 сентября 2008

Поскольку свойство Length для System.String является Int32, я бы предположил, что максимальная длина будет 2 147 483 647 символов (максимальный размер Int32). Если бы это позволило дольше, вы не можете проверить длину, так как это не получится.

26 голосов
/ 11 августа 2014

Для тех, кто опаздывает на эту тему поздно, я мог видеть, что из-за hitcan "вы, вероятно, не должны этого делать", может кто-то спросить, что он должен делать ...

Класс StringBuilder часто является легкой заменой. Рассмотрим один из потоковых классов , особенно если ваши данные поступают из файла.

Проблема с s += "stuff" заключается в том, что он должен выделить совершенно новую область для хранения данных, а затем скопировать в нее все старые данные, а также новый материал - КАЖДУЮ И КАЖДУЮ ПЕРЕДАЧУ. Таким образом, добавление пяти байтов к 1000000 с s += "stuff" чрезвычайно дорого. Если вам нужно просто написать пять байтов до конца и продолжить свою программу, вам нужно выбрать класс, который оставляет место для роста:

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

StringBuilder будет автоматически расти при удвоении при достижении лимита. Итак, вы увидите боль роста один раз в начале, один раз в 5000 байтов, снова в 10 000, снова в 20 000. Добавление строк будет вызывать боль при каждой итерации цикла.

7 голосов
/ 04 августа 2015

Максимальная длина строки на моей машине составляет 1 073 741 791 .

Видите ли, строки не ограничены целым числом, как принято считать.

За исключением ограничений памяти, строки не могут содержать более 2 30 ( 1 073 741 824 ) символов, поскольку Microsoft CLR (Common Language Runtime) накладывает ограничение в 2 ГБ. 33 больше, чем позволял мой компьютер.

Теперь, вот что вы можете попробовать сами.

Создайте новое консольное приложение C # в Visual Studio, а затем скопируйте / вставьте основной метод здесь:

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

}

Мои результаты были следующими:

Струнный тест, Николас Джон Джозеф Тейлор

Теоретически, C # должен поддерживать строку int.MaxValue, но мы запускаем до этого не хватает памяти.

Это быстрый тест для сужения результатов, чтобы найти максимум поддерживаемая длина строки.

Тест начинается ... сейчас:

s.Length = 1000000000 в 08.05.2009 12: 06

Возникло исключение типа 'System.OutOfMemoryException'. в 05.08.2009 12:06. После прореживания значение приращения 100000000.

Исключение типа 'System.OutOfMemoryException' было сгенерировано. в 05.08.2009 12:06. После прореживания значение приращения 10000000. s.Length = 1010000000 в 05.08.2009 12:06 s.Length = 1020000000 в 08.05.2009 12:06 s.Length = 1030000000 в 08.05.2009 12:06 s.Length = 1040000000 в 05.08.2009 12:06 s.Length = 1050000000 в 05/05/2019 12:06 s.Length = 1060000000 в 05.05.2009 12:06 s.Length = 1070000000 от 08.05.2009 12: 06

Исключение типа 'System.OutOfMemoryException' было сгенерировано. в 05.08.2009 12:06. После прореживания значение инкремента равно 1000000. s.Length = 1071000000 в 05.08.2009 12:06 s.Length = 1072000000 в 05.08.2009 12:06 s.Length = 1073000000 в 08.05.2009 12: 06

Исключение типа 'System.OutOfMemoryException' было сгенерировано. в 05.08.2009 12:06. После прореживания значение инкремента равно 100000. s.Length = 1073100000 в 05.08.2009 12:06 s.Length = 1073200000 в 05/05/2019 12:06 s.Length = 1073300000 в 08/05/2019 12:06 s.Length = 1073400000 в 05.05.2009, 12:06 s.Length = 1073500000 в 08.05.2009 12:06 s.Length = 1073600000 в 05.08.2009 12:06 s.Length = 1073700000 в 08.05.2009 12: 06

Исключение типа 'System.OutOfMemoryException' было сгенерировано. в 05.08.2009 12:06. После прореживания значение инкремента равно 10000. s.Length = 1073710000 в 05.08.2009 12:06 s.Length = 1073720000 в 05/05/2019 12:06 s.Length = 1073730000 в 08/05/2019 12:06 s.Length = 1073740000 от 08.05.2009 12: 06

Исключение типа 'System.OutOfMemoryException' было сгенерировано. в 05.08.2009 12:06. После прореживания значение инкремента равно 1000. s.Length = 1073741000 в 08.05.2009 12: 06

Было сгенерировано исключение типа System.OutOfMemoryException. в 05.08.2009 12:06. После прореживания значение инкремента равно 100. s.Length = 1073741100 в 05.08.2009 12:06 s.Length = 1073741200 в 05.08.2009 12:06 s.Length = 1073741300 в 05.08.2009 12:07 s.Length = 1073741400 в 05.05.2009, 12:07 s.Length = 1073741500 в 08.05.2009 12:07 s.Length = 1073741600 в 05.08.2009 12:07 s.Length = 1073741700 в 08.05.2009 12: 07

Исключение типа 'System.OutOfMemoryException' было сгенерировано. в 05.08.2009 12:07. После прореживания значение инкремента равно 10. s.Length = 1073741710 в 05.08.2009, 12:07 s.Length = 1073741720 в 05.08.2009 12:07 s.Length = 1073741730 в 05.05.2009 12:07 s.Length = 1073741740 в 05.05.2009, 12:07 s.Length = 1073741750 в 08.05.2009 12:07 s.Length = 1073741760 в 05.08.2009 12:07 s.Length = 1073741770 в 05/05/2019 12:07 s.Length = 1073741780 в 05/05/2019 12:07 s.Length = 1073741790 от 08.05.2009 12: 07

Было сгенерировано исключение типа System.OutOfMemoryException. в05.08.2009 12:07. После прореживания значение инкремента равно 1. s.Length = 1073741791 в 05.08.2009 12: 07

Исключение типа 'System.OutOfMemoryException' было сгенерировано. в 05.08.2009 12:07. После прореживания значение Приращения равно 0. Тест полный.

Максимальная длина строки - 1073741791.

Нажмите любую клавишу для продолжения.

Максимальная длина строки на моей машине - 1073741791.

Я был бы очень признателен, если бы люди могли опубликовать свои результаты в виде комментария ниже.

Будет интересно узнать, получают ли люди одинаковые или разные результаты.

2 голосов
/ 26 сентября 2008

200 мегабайтов ... в этот момент ваше приложение переходит в режим виртуальной остановки, в нем имеется почти рабочая память рабочего набора, и операционные системы начинают работать так, как будто вам нужно перезагрузиться.

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
1 голос
/ 26 сентября 2008

Поскольку String.Length является целым числом (то есть псевдонимом для Int32), его размер ограничен Int32.MaxValue символами Юникода. ; -)

...