2008-09-26 4 views
186

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

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

ответ

270

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

Это одна из тех ситуаций, когда "If you have to ask, you're probably doing something wrong."

47

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

+10

+1 Хороший вывод – 2011-03-11 11:10:51

+2

@ m.edmondson: На самом деле я не уверен. [Array] (https://msdn.microsoft.com/en-us/library/system.array%28v=vs.110%29.aspx) для экземпляров имеет также «LongLength», а поток использует `long `как длину. Хотя это правильный ответ, это точный способ измерения этого. – 2015-01-27 19:59:05

+0

Но первые два бита используются для показа ASCII/не-ASCII как [эта статья] (https://www.codeproject.com/Articles/3377/Strings-UNDOCUMENTED), поэтому он должен быть 2^30 = 1 073 741 824 – Saito 2017-02-10 12:04:53

0

Поскольку string.length представляет собой целое число (которое является псевдонимом для Int32) его размер ограничен символам Int32.MaxValue Юникода;)

60

Основываясь на моем весьма научный и точном эксперименте, вершины на моей машине задолго до 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 
} 
+25

Применение двоичного поиска здесь, вероятно, поможет вам найти этот ответ намного быстрее ... – Mario 2010-07-12 21:08:58

+24

+1 для использования ответных тестов. – 2011-01-04 00:46:03

1

200 мегов ... и в этот момент ваше приложение перемалывает к виртуальной остановке, имеет около кабриолета рабочего набора памяти, а также о/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 
20

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

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

Проблема с s = s + "stuff" заключается в том, что она должна выделить совершенно новую область для хранения данных, а затем скопировать все старые данные в нее плюс новый материал - КАЖДОЙ И КАЖДОЙ ОБРАБОТКИ LOOP. Таким образом, добавление 5 байтов в 1 миллион с s = s + «материал» чрезвычайно дорого. Если вы хотите просто написать 5 байт до конца и продолжить свою программу, вам нужно выбрать класс, который оставляет место для роста.

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

StringBuilder будет auto-grow by doubling когда это предел хит. Таким образом, вы увидите рост боли один раз в начале, один раз на 5000 байт, снова на 10000, снова на 20000. При добавлении строк будет страдать всякая итерация цикла.

5

Строка не ограничена числом, как это принято считать

Ограничения памяти в стороне, Строки не могут иметь более 2 (1073741824) символов, так как предел 2GB налагаются Microsoft CLR (Common Language Runtime).

Надеюсь, это может измениться в будущем.

0

Обратите внимание, что BinaryWriter.Write (string) записывает длину строки как символ без знака (один байт)!

Смежные вопросы