質問
.NETで作成できる最長の文字列は何ですか? String
クラスのドキュメントは、私が見る限りこの質問については言及していないため、信頼できる回答には内部の知識が必要になる場合があります。 64ビットシステムで最大の変更はありますか?
[これは実用よりも好奇心が求められます-巨大な文字列を使用するコードを作成するつもりはありません!]
解決
理論上の制限は2,147,483,647かもしれませんが、実際的な制限はそれに近いものではありません。 .NETプログラムの単一のオブジェクトは2GBを超えることはできず、文字列型はUnicode(各文字に2バイト)を使用するため、できることは1,073,741,823ですが、それを割り当てることはできません32ビットマシン。
他のヒント
非常に科学的かつ正確な実験に基づいて、1,000,000,000文字よりもずっと前にマシンで最高になります。 (より正確なピンポイントを得るために、以下のコードを実行しています)。
更新:
数時間後、私はあきらめました。最終結果: System.OutOfMemoryException
を1,000,000,000文字で即座に指定して、100,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
}
System.String
の Length
プロパティは Int32
であるため、最大長は2,147,483,647文字(最大 Int32
サイズ)。それが長くなると、失敗するため、長さを確認できませんでした。
このトピックに遅れて来る人にとっては、hitscanの「あなたはおそらくそれをすべきではない」ことがわかりました。誰かが何をすべきかを尋ねる可能性があります&#8230;
StringBuilder 多くの場合、クラスは簡単に置き換えられます。 ストリームベースのクラスのいずれかを検討します特に、データがファイルからのものである場合。
s + =&quot; stuff&quot;
の問題は、データを保持するために完全に新しい領域を割り当ててから、古いデータすべてと新しいものをコピーする必要があることです-各そして、すべてのループの繰り返し。そのため、 s + =&quot; stuff&quot;
で1,000,000に5バイトを追加すると、非常にコストがかかります。
末尾に5バイトを書き込んでプログラムを続行するだけであれば、成長の余地を残したクラスを選択する必要があります。
StringBuilder sb = new StringBuilder(5000);
for (; ; )
{
sb.Append("stuff");
}
StringBuilder
は制限に達したときに自動倍増します。したがって、開始時に1回、5,000バイトに1回、10,000に1回、再度20,000に成長の痛みが見られます。文字列を追加すると、ループを繰り返すたびに痛みが生じます。
私のマシン上の文字列の最大長 は 1,073,741,791 です。
ご存知のように、文字列は一般的に考えられているように整数に制限されていません。
メモリの制限は別として、Microsoft CLR(Common Language Runtime)によって2GBの制限が課されているため、文字列には2 30 ( 1,073,741,824 )文字を超えることはできません。私のコンピューターが許す以上に33個。
さて、ここで試してみてください。
Visual Studioで新しいC#コンソールアプリを作成し、メインメソッドをここにコピーして貼り付けます:
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();
}
私の結果は次のとおりです。
ストリングテスト、Nicholas John Joseph Taylor
理論的には、C#はint.MaxValueの文字列をサポートする必要がありますが、実行します それまではメモリ不足です。
これは、最大値を見つけるために結果を絞り込むクイックテストです サポートされている文字列の長さ。
テストが始まります...今:
s.Length = 1000000000 2019年8月5日12時06分
「System.OutOfMemoryException」タイプの例外がスローされました。で 08/05/2019 12:06。間引き後、Incrementの値は 100000000。
「System.OutOfMemoryException」タイプの例外がスローされました。で 08/05/2019 12:06。間引き後、Incrementの値は 10000000。s.Length = 1010000000 at 08/05/2019 12:06 s.Length = 1020000000 at 08/05/2019 12:06 s.Length = 1030000000 at 08/05/2019 12:06 s.Length = 1040000000 at 08/05/2019 12:06 s.Length。= 1050000000 at 08/05/2019 12:06 s.Length = 1060000000 at 08/05/2019 12:06 s.Length = 08/05/2019 12:06で1070000000
「System.OutOfMemoryException」タイプの例外がスローされました。で 08/05/2019 12:06。間引き後、Incrementの値は1000000です。 s.Length = 1071000000 at 08/05/2019 12:06 s.Length = 1072000000 at 08/05/2019 12:06 s.Length = 1073000000 at 08/05/2019 12:06
「System.OutOfMemoryException」タイプの例外がスローされました。で 08/05/2019 12:06。間引き後、Incrementの値は100000です。 s.Length = 1073100000 at 08/05/2019 12:06 s.Length = 1073200000 at 2019年5月8日12:06秒長さ= 1073300000、2019年8月5日12:06秒長さ= 1073400000 at 08/05/2019 12:06 s.Length = 1073500000 at 08/05/2019 12:06 s.Length = 1073600000 at 08/05/2019 12:06 s.Length。= 1073700000 2019年5月8日12時06分
「System.OutOfMemoryException」タイプの例外がスローされました。で 08/05/2019 12:06。間引き後、Incrementの値は10000です。 s.Length = 1073710000 at 08/05/2019 12:06 s.Length = 1073720000 at 2019年8月5日12:06秒長さ= 1073730000 2019年8月5日12:06秒長さ= 1073740000 at 08/05/2019 12:06
「System.OutOfMemoryException」タイプの例外がスローされました。で 08/05/2019 12:06。間引き後、Incrementの値は1000です。 s.Length = 083742019 at 08/05/2019 12:06
「System.OutOfMemoryException」タイプの例外がスローされました。で 08/05/2019 12:06。間引き後、Incrementの値は100です。 s.Length = 1073741100 at 08/05/2019 12:06 s.Length = 1073741200 at 2019年8月5日12:06 s。長さ= 1073741300 at 08/05/2019 12:07 s。長さ= 1073741400 at 08/05/2019 12:07 s.Length = 1073741500 at 08/05/2019 12:07 s。長さ= 1073741600 at 08/05/2019 12:07 s。長さ= 1073741700 2019年8月5日12時07分
「System.OutOfMemoryException」タイプの例外がスローされました。で 08/05/2019 12:07。間引き後、Incrementの値は10です。 s.Length = 1073741710 at 08/05/2019 12:07 s.Length = 1073741720 at 2019年8月5日12:07 s.Length = 1073741730 at 08/05/2019 12:07 s.Length = 1073741740 at 08/05/2019 12:07 s.Length = 1073741750 at 08/05/2019 12:07 s。長さ= 1073741760 at 08/05/2019 12:07 s。長さ= 1073741770 2019年5月8日12:07秒長さ= 1073741780 2019年8月5日12:07秒長さ = 1073741790 at 08/05/2019 12:07
「System.OutOfMemoryException」タイプの例外がスローされました。で 08/05/2019 12:07。 dの後
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
String.Length
は整数( Int32
のエイリアス)であるため、そのサイズは Int32.MaxValue
unicode文字に制限されます。 ;-)