Ho bisogno di creare un elenco di combinazioni di numeri. I numeri sono piuttosto piccoli quindi posso usare bytepiuttosto 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, BitArrayma 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.