Какова максимально возможная длина строки .NET?

StackOverflow https://stackoverflow.com/questions/140468

  •  02-07-2019
  •  | 
  •  

Вопрос

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

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

Это было полезно?

Решение

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

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

Другие советы

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

ОБНОВЛЯТЬ:Через несколько часов я сдался.Окончательные результаты:Может быть намного больше, чем 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
}

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

Для тех, кто поздно подошел к этой теме, я мог заметить, что надпись «Вам, вероятно, не следует этого делать» может заставить кого-то спросить, что им следует делать…

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

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

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

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

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

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

Помимо ограничений памяти, строки не могут иметь более 230 (1,073,741,824) символов, поскольку ограничение в 2 ГБ наложено Microsoft CLR (Common Language Runtime).На 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 на 05.08.2019 12:06

Было выдано исключение типа System.OutOfMemoryException.в 08.05.2019 12:06.После убийства значение приращения составляет 100000000.

Выдано исключение типа System.OutOfMemoryException.в 08.05.2019 12:06.После убийства значение приращения составляет 10000000.S.Length = 1010000000 в 08.05.2019 12:06 S.Length = 1020000000 в 08.05.2019 12:06 S.Length = 1030000000 в 08/05/2019 12:06 S.Length = 1040000000 в 08/ 05/2019 12:06 S.Length = 1050000000 в 08.05.2019 12:06 S.Length = 1060000000 в 08.05.2019 12:06 S.Length = 1070000000 в 08/05/2019 12:06

Выдано исключение типа System.OutOfMemoryException.в 08.05.2019 12:06.После прореживания значение приращения составляет 1000000.S.Length = 1071000000 от 08/05/2019 12:06 S.Length = 1072000000 в 08.05.2019 12:06 S.Length = 1073000000 в 08.05.2019 12:06

Выдано исключение типа System.OutOfMemoryException.в 08.05.2019 12:06.После прореживания значение приращения равно 100000.S.Length = 1073100000 от 08/05/2019 12:06 S.Length = 1073200000 в 08.05.2019 12:06 S.Length = 1073300000 в 08/05/2019 12:06 S.Length = 1073400000 в 08/05/2019 12:06 S.Length = 1073400000 в 08/05/2019 05/2019 12:06 S.Length = 1073500000 в 08.05.2019 12:06 S.Length = 1073600000 в 08.05.2019 12:06 S.Length = 1073700000 в 08.05.2019 12:06

Выдано исключение типа System.OutOfMemoryException.в 08.05.2019 12:06.После прореживания значение приращения равно 10000.S.Length = 1073710000 от 08/05/2019 12:06 S.Length = 1073720000 от 08/05/2019 12:06 S.Length = 1073730000 в 08/05/2019 12:06 S.Length = 1073740000 на 08/05/2019 12:06 = 1073740000 в 08/05/2019 12:06. 05/2019 12:06

Выдано исключение типа System.OutOfMemoryException.в 08.05.2019 12:06.После прореживания значение приращения равно 1000.s.Length = 1073741000 на 05.08.2019 12:06

Выдано исключение типа System.OutOfMemoryException.в 08.05.2019 12:06.После прореживания значение приращения равно 100.S.Length = 1073741100 от 08/05/2019 12:06 S.Length = 1073741200 на 08.05.2019 12:06 S.Length = 1073741300 в 08/05/2019 12:07 05/2019 12:07 S.Length = 1073741500 в 08.05.2019 12:07 S.Length = 1073741600 в 08.05.2019 12:07 S.Length = 1073741700 в 08/05/2019 12:07

Выдано исключение типа System.OutOfMemoryException.в 08.05.2019 12:07.После прореживания значение приращения равно 10.S.Length = 1073741710 от 08/05/2019 12:07 S.Length = 1073741720 в 08/05/2019 12:07 S.Length = 1073741730 в 08/05/2019 12:07 S.Length = 1073741740 в 08/2019 12:07. 05/2019 12:07 S.Length = 1073741750 в 08.05.2019 12:07 S.Length = 1073741760 от 08/05/2019 12:07 S.Length = 1073741770 в 08.05.2019 12:07 с. Длина = 1073741780 от 08.05.2019 12:07 S.Length = 1073741790 от 08/05/2019 12:07

Выдано исключение типа System.OutOfMemoryException.в 08.05.2019 12:07.После прореживания значение приращения равно 1.s.Length = 1073741791 на 05.08.2019 12:07

Выдано исключение типа System.OutOfMemoryException.в 08.05.2019 12:07.После прореживания значение приращения равно 0.Проверка полна.

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top