Tenho necessidade de criar uma lista de combinações de números. Os números são muito pequenos para que eu possa usar byte
em 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, BitArray
mas 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.