Tenho necessidade de criar uma lista de combinações de números. Os números são muito pequenos para que eu possa usar byteem vez de int. No entanto, requer muitos loops aninhados para obter todas as combinações possíveis. Estou me perguntando se existe uma maneira mais eficiente de fazer o que procuro. O código até agora é:
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});
}
Eu estava pensando em usar algo como um, BitArraymas não tenho certeza de como poderia incorporá-lo.
Qualquer recomendação seria grandemente apreciada. Alternativamente, talvez esta seja a maneira mais rápida de fazer o que desejo?
EDITAR Alguns pontos rápidos (e desculpas por não colocá-los na postagem original):
- Os números e a ordem deles (2, 3, 4, 3, 4, 3, 3 etc) são muito importantes, então usar uma solução como Gerar Permutações usando LINQ não ajudará porque os máximos em cada 'coluna' são diferente
- Não sou um matemático, então peço desculpas se não estou usando os termos técnicos como 'permutações' e 'combinações' corretamente :)
- Eu não preciso preencher todas estas combinações de uma vez - eu não pode simplesmente pegar um ou outro com base em um índice
- Usar
byteé mais rápido do que usarint, garanto . Também é muito melhor no uso de memória ter mais de 67 milhões de matrizes de bytes em vez de ints - Meu objetivo final aqui é procurar uma alternativa mais rápida aos loops aninhados.
- Eu considerei usar programação paralela, mas devido à natureza iterativa do que estou tentando alcançar, não consegui encontrar uma maneira de fazer isso com sucesso (mesmo com
ConcurrentBag) - no entanto, estou feliz por estar errado :)
CONCLUSÃO
Caramiriel forneceu uma boa micro-otimização que economiza algum tempo dos loops, então eu marquei essa resposta como correta. Eric também mencionou que é mais rápido pré-alocar a Lista. Mas, neste estágio, parece que os loops aninhados são de fato a maneira mais rápida possível de fazer isso (deprimente, eu sei!).
Se você quiser tentar exatamente o que eu estava tentando fazer benchmark StopWatch, vá com 13 loops contando até 4 em cada loop - isso perfaz cerca de 67m + linhas na lista. Na minha máquina (i5-3320M 2.6GHz) leva cerca de 2.2s para fazer a versão otimizada.