Мне нужно составить список комбинаций чисел. Цифры довольно маленькие, поэтому я могу использовать byte
вместо int
. Однако для получения всех возможных комбинаций требуется много вложенных циклов. Мне интересно, есть ли более эффективный способ сделать то, что мне нужно. Код на данный момент:
var data = new List<byte[]>();
for (byte a = 0; a < 2; a++)
for (byte b = 0; b < 3; b++)
for (byte c = 0; c < 4; c++)
for (byte d = 0; d < 3; d++)
for (byte e = 0; e < 4; e++)
for (byte f = 0; f < 3; f++)
for (byte g = 0; g < 3; g++)
for (byte h = 0; h < 4; h++)
for (byte i = 0; i < 2; i++)
for (byte j = 0; j < 4; j++)
for (byte k = 0; k < 4; k++)
for (byte l = 0; l < 3; l++)
for (byte m = 0; m < 4; m++)
{
data.Add(new [] {a, b, c, d, e, f, g, h, i, j, k, l, m});
}
Я подумывал об использовании чего-то вроде a, BitArray
но не уверен, как это можно сделать.
Приветствуются любые рекомендации. Или, может быть, это самый быстрый способ делать то, что я хочу?
ИЗМЕНИТЬ Пара быстрых замечаний (и извинения, я не поместил их в исходный пост):
- Числа и порядок их (2, 3, 4, 3, 4, 3, 3 и т. Д.) Очень важны, поэтому использование такого решения, как Генерация перестановок с использованием LINQ , не поможет, потому что максимумы в каждом «столбце» равны разные
- Я не математик, поэтому прошу прощения, если неправильно использую такие технические термины, как «перестановки» и «комбинации» :)
- Я действительно нужно заполнить все эти комбинации сразу - я не могу просто взять один или другой на основе индекса
- Использование
byte
быстрее, чем использованиеint
, я гарантирую это. Также намного лучше использовать память, чтобы иметь массивы байтов более 67 млн, а не целые числа. - Моя конечная цель - найти более быструю альтернативу вложенным циклам.
- Я подумывал об использовании параллельного программирования, но из-за итеративного характера того, чего я пытаюсь достичь, я не смог найти способ сделать это успешно (даже с
ConcurrentBag
) - однако я счастлив, что ошибся :)
ВЫВОД
Карамириэль предоставил хорошую микрооптимизацию, которая сокращает время циклов, поэтому я отметил этот ответ как правильный. Эрик также упомянул, что быстрее разместить список заранее. Но на данном этапе кажется, что вложенные циклы на самом деле являются самым быстрым из возможных способов сделать это (я знаю, удручающе!).
Если вы хотите попробовать именно то, что я пытался протестировать StopWatch
, используйте 13 циклов, считая до 4 в каждом цикле, что составляет около 67 миллионов строк в списке. На моей машине (i5-3320M 2,6 ГГц) оптимизированная версия занимает около 2,2 с.