StringBuilderを使用して文字列をアセンブルすると、処理が600倍になります(文字列に追加するたびにオブジェクトが繰り返し作成されるのを防ぐため)。
ループ前(容量を初期化すると、StringBuilderでバッキング配列が再作成されなくなります):
StringBuilder sb = new StringBuilder(1000000 * ReadLength);
ループ中:
sb.Append(all.Substring(randomPos, ReadLength) + Environment.NewLine);
ループ後:
readString = sb.ToString();
文字列の代わりにchar配列を使用して値を抽出すると、Substring()の呼び出し時に発生するオブジェクトの作成を回避できるため、さらに30%の改善が得られます。
ループ前:
char[] chars = all.ToCharArray();
ループ中:
sb.Append(chars, randomPos, ReadLength);
sb.AppendLine();
編集(StringBuilderを使用せず、300msで実行される最終バージョン):
char[] chars = all.ToCharArray();
var iterations = 1000000;
char[] results = new char[iterations * (ReadLength + 1)];
GetRandomStrings(len, iterations, ReadLength, chars, results, 0);
string s = new string(results);
private static void GetRandomStrings(int len, int iterations, int ReadLength, char[] chars, char[] result, int resultIndex)
{
Random random = new Random();
int i = 0, index = resultIndex;
while (i < iterations && len - 100 > 0) //len is 3000000
{
var i1 = len - ReadLength;
int randomPos = random.Next() % i1;
Array.Copy(chars, randomPos, result, index, ReadLength);
index += ReadLength;
result[index] = Environment.NewLine[0];
index++;
i++;
}
}