Какова максимальная длина строки .NET?
Какова самая длинная строка, которая может быть создана в .NET? Документы для класса String
молчат по этому вопросу, насколько я могу судить, поэтому для авторитетного ответа может потребоваться некоторое знание внутренних компонентов. Будет ли максимальное изменение в 64-битной системе?
[Это больше интересуется любопытством, чем для практического использования - я не собираюсь создавать какой-либо код, который использует гигантские строки!]
Ответы
Ответ 1
Теоретический предел может составлять 2 147 483 647, но практический предел далеко не таков. Поскольку ни один объект в .NET-программе не может быть больше 2 ГБ, а строковый тип использует Unicode (2 байта на каждый символ), лучшее, что вы можете сделать, это 1 073 741 823, но вы вряд ли когда-либо сможете выделить его на 32-битная машина.
Это одна из тех ситуаций, когда "если вам нужно спросить, вы, вероятно, делаете что-то не так".
Ответ 2
Исходя из моего очень научного и точного эксперимента, он превосходит мою машину задолго до 1 000 000 000 символов. (Я все еще использую код ниже, чтобы получить лучшее определение).
ОБНОВЛЕНИЕ: Через несколько часов я сдался. Окончательные результаты: могут превышать 100 000 000 символов, мгновенно System.OutOfMemoryException
исключение 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
}
Ответ 3
Поскольку свойство Length
объекта System.String
имеет Int32
, я предполагаю, что максимальная длина будет составлять 2 147 483 647 символов (максимальный размер Int32
). Если это позволит больше, вы не можете проверить длину, так как это не получится.
Ответ 4
Для тех, кто опаздывает на эту тему поздно, я мог видеть, что отсканированное "вы, вероятно, не должны этого делать" может заставить кого-то спросить, что им делать...
Класс StringBuilder часто является легкой заменой. Рассмотрим один из потоковых классов, особенно если ваши данные поступают из файла.
Проблема с s += "stuff"
заключается в том, что ему нужно выделить совершенно новую область для хранения данных, а затем скопировать в нее все старые данные плюс новый материал - EACH AND EVERY LOOP ITERATION. Таким образом, добавление пяти байтов к 1000000 с помощью s += "stuff"
чрезвычайно дорого. Если вам нужно просто написать пять байтов до конца и продолжить свою программу, вам нужно выбрать класс, который оставляет место для роста:
StringBuilder sb = new StringBuilder(5000);
for (; ; )
{
sb.Append("stuff");
}
StringBuilder
будет автоматически расти при удвоении при достижении лимита. Итак, вы увидите боль роста один раз в начале, один раз в 5000 байтов, снова в 10 000, снова в 20 000. Добавление строк будет причинять боль при каждой итерации цикла.
Ответ 5
Максимальная длина строки на моей машине составляет 1 073 741 791.
Видите ли, строки не ограничены целым числом, как принято считать.
Помимо ограничений памяти, строки не могут содержать более 2 30 (1 073 741 824) символов, так как Microsoft CLR (Common Language Runtime) накладывает ограничение в 2 ГБ. 33 больше, чем позволил мой компьютер.
Теперь, вот что вы можете попробовать сами.
Создайте новое консольное приложение С# в 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();
}
Мои результаты были следующими:
Струнный тест, Николас Джон Джозеф Тейлор
Теоретически, С# должен поддерживать строку int.MaxValue, но до этого у нас не хватало памяти.
Это быстрый тест для сужения результатов и определения максимальной поддерживаемой длины строки.
Тест начинается... сейчас:
s.Length = 1000000000 в 05.08.2009 12:06
Исключение типа 'System.OutOfMemoryException' было сгенерировано. в 08.05.2009 12:06. После прореживания значение инкремента равно 100000000.
Исключение типа 'System.OutOfMemoryException' было сгенерировано. в 08.05.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 в 08.05.2009 12:06 s.Length = 1050000000 в 08.05.2009 12:06 s.Length = 1060000000 в 08.05.2009 12:06 s.Length = 1070000000 в 05.08.2009 12:06
Исключение типа 'System.OutOfMemoryException' было сгенерировано. в 08.05.2009 12:06. После децимации значение Приращения равно 1000000. s.Length = 1071000000 в 05.08.2009 12:06 s.Length = 1072000000 в 08.05.2009 12:06 s.Length = 1073000000 в 08.05.2009 12: 06
Исключение типа 'System.OutOfMemoryException' было сгенерировано. в 08.05.2009 12:06. После децимации значение приращения равно 100000. s.Length = 1073100000 на 05.08.2009 г. 12:06 s.Length = 1073200000 на 05.05.2009 г. 12:06 s.Length = 1073300000 на 08.05.2009 г. 12: 06 s.Length = 1073400000 в 05.05.2009, 12:06 s.Length = 1073500000 в 08.05.2009, 12:06 s.Length = 1073600000 в 08.05.2009, 12:06 s.Length = 1073700000 в 05.08.2009 12:06
Исключение типа 'System.OutOfMemoryException' было сгенерировано. в 08.05.2009 12:06. После децимации значение Приращения равно 10000. s.Length = 1073710000 на 05.08.2009 12:06 s.Length = 1073720000 на 05.05.2009 12:06 s.Length = 1073730000 на 08.05.2009 12: 06 s.Length = 1073740000 в 05.08.2009 12:06
Исключение типа 'System.OutOfMemoryException' было сгенерировано. в 08.05.2009 12:06. После прореживания значение Приращения равно 1000. s.Length = 1073741000 в 05.08.2009 12:06
Исключение типа 'System.OutOfMemoryException' было сгенерировано. в 08.05.2009 12:06. После децимации значение Приращения равно 100. s.Length = 1073741100 на 05.08.2009, 12:06 s.Length = 1073741200 на 05.05.2009, 12:06 s.Length = 1073741300 на 08.05.2009, 12: 07 s.Length = 1073741400 в 05.08.2009 12:07 s.Length = 1073741500 в 08.05.2009 12:07 s.Length = 1073741600 в 05.08.2009 12:07 s.Length = 1073741700 в 05.08.2009 12:07
Исключение типа 'System.OutOfMemoryException' было сгенерировано. в 08.05.2009 12:07. После децимации значение Приращения равно 10. s.Length = 1073741710 в 05.08.2009 12:07 s.Length = 1073741720 в 08.05.2009 12:07 s.Length = 1073741730 в 08.05.2009 12: 07 s.Length = 1073741740 в 05.05.2009, 12:07 s.Length = 1073741750 в 08.05.2009, 12:07 s.Length = 1073741760 в 08.05.2009, 12:07 s.Length = 1073741770 в 05.08.2009 12:07 s.Length = 1073741780 в 05.08.2009 12:07 s.Length = 1073741790 в 08.05.2009 12:07
Исключение типа 'System.OutOfMemoryException' было сгенерировано. в 08.05.2009 12:07. После прореживания значение Приращения равно 1. s.Length = 1073741791 в 05.08.2009 12:07
Исключение типа 'System.OutOfMemoryException' было сгенерировано. в 08.05.2009 12:07. После прореживания значение Приращения равно 0. Тест завершен.
Максимальная длина строки 1073741791.
Нажмите любую клавишу для продолжения.
Максимальная длина строки на моей машине составляет 1073741791.
Я был бы очень признателен, если бы люди могли опубликовать свои результаты в виде комментария ниже.
Будет интересно узнать, получают ли люди одинаковые или разные результаты.
Ответ 6
200 мегабайт... в этот момент ваше приложение превращается в виртуальную остановку, имеет около рабочей памяти набора команд, и o/s начинает действовать так, как вам нужно будет перезагрузиться.
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
Ответ 7
Поскольку String.Length
является целым числом (псевдонимом для Int32
), его размер ограничен Unicode-символами Int32.MaxValue
. ;-)
Ответ 8
Обратите внимание, что BinaryWriter.Write(string) записывает длину строки как unsigned char (один байт)!