Ho bisogno di creare un elenco di combinazioni di numeri. I numeri sono piuttosto piccoli quindi posso usare byte
piuttosto che int
. Tuttavia richiede molti cicli annidati per ottenere ogni possibile combinazione. Mi chiedo se esista un modo più efficiente per fare ciò che cerco. Il codice finora è:
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});
}
Stavo pensando di utilizzare qualcosa come a, BitArray
ma non sono sicuro di come potrei incorporarlo.
Ogni consiglio sarebbe molto apprezzato. In alternativa, forse questo è il modo più veloce per fare quello che voglio?
MODIFICA Un paio di brevi punti (e mi scuso per non averli inseriti nel post originale):
- I numeri e l'ordine di essi (2, 3, 4, 3, 4, 3, 3 ecc.) Sono molto importanti, quindi l'utilizzo di una soluzione come Generare permutazioni usando LINQ non aiuta perché i massimi in ogni 'colonna' sono diverso
- Non sono un matematico, quindi mi scuso se non utilizzo correttamente i termini tecnici come "permutazioni" e "combinazioni" :)
- Io faccio bisogno di compilare tutte queste combinazioni in una sola volta - non posso prendere uno o l'altro sulla base di un indice di
- Usare
byte
è più veloce dell'usoint
, lo garantisco . È anche molto meglio sull'utilizzo della memoria avere più di 67 milioni di matrici di byte piuttosto che interi - Il mio obiettivo finale qui è cercare un'alternativa più veloce ai loop annidati.
- Ho considerato l'utilizzo della programmazione parallela, ma a causa della natura iterativa di ciò che sto cercando di ottenere, non sono riuscito a trovare un modo per farlo con successo (anche con
ConcurrentBag
) - tuttavia sono felice di essere smentito :)
CONCLUSIONE
Caramiriel ha fornito una buona micro-ottimizzazione che riduce un po 'di tempo ai loop, quindi ho contrassegnato la risposta come corretta. Eric ha anche detto che è più veloce pre-allocare l'elenco. Ma, in questa fase, sembra che i cicli annidati siano in realtà il modo più veloce possibile per farlo (deprimente, lo so!).
Se vuoi provare esattamente quello con cui stavo cercando di fare il benchmark StopWatch
, vai con 13 loop che contano fino a 4 in ogni loop - che fa circa 67m + linee nell'elenco. Sulla mia macchina (i5-3320M 2.6GHz) ci vogliono circa 2.2s per fare la versione ottimizzata.