Вы получаете OutOfMemoryException
, потому что внутри цикла вы выделяете строку и сохраняете ее в ArrayList
. Строки должны оставаться в памяти до тех пор, пока мусор не будет ArrayList
и ваш цикл не создаст больше строк, чем вы сможете сохранить.
Если вы просто хотите проверить строку на наличие условия, вы должны поместить проверку в цикл:
for ( ... some crazy loop ...) {
var word = ... create word ...
if (!WordPassesTest(word)) {
Console.WriteLine(word + " failed test.");
return false;
}
}
return true;
Тогда вам нужно только хранилище для одного слова. Конечно, если цикл достаточно сумасшедший, он не прекратится до конца вселенной, как мы ее знаем.
Если вам нужно выполнить много вложенных, но похожих циклов, вы можете использовать рекурсию для упрощения кода. Вот пример, который не является невероятно эффективным, но, по крайней мере, он прост:
Char[] chars = "ABCD".ToCharArray();
IEnumerable<String> GenerateStrings(Int32 length) {
if (length == 0) {
yield return String.Empty;
yield break;
}
var strings = chars.SelectMany(c => GenerateStrings(length - 1), (c, s) => c + s);
foreach (var str in strings)
yield return str;
}
Вызов GenerateStrings(3)
сгенерирует все строки длины 3, используя ленивый анализ (поэтому для строк не требуется дополнительная память).
Основываясь на IEnumerable
, генерирующем ваши строки, вы можете создавать примитивы для буферизации и обработки буферов строк. Простым решением является использование Reactive Extensions для .NET. Здесь у вас уже есть примитив Buffer
:
GenerateStrings(3)
.ToObservable()
.Buffer(10)
.Subscribe(list => ... ship the list to another computer and process it ...);
Лямбда в Subscribe
будет вызываться с List<String>
, содержащим не более 10 строк (параметр, указанный в вызове Buffer
).
Если у вас нет бесконечного числа компьютеров, вам все равно придется извлекать компьютеры из пула и возвращать их обратно в пул только после завершения вычислений.
Из комментариев к этому вопросу должно быть очевидно, что вы не сможете обработать 26 ^ 30 строк, даже если в вашем распоряжении несколько компьютеров.