J'ai besoin de créer une liste de combinaisons de nombres. Les nombres sont assez petits donc je peux utiliser byte
plutôt que int
. Cependant, il nécessite de nombreuses boucles imbriquées afin d'obtenir toutes les combinaisons possibles. Je me demande s'il existe une manière plus efficace de faire ce que je recherche. Le code jusqu'à présent est:
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});
}
J'envisageais d'utiliser quelque chose comme a BitArray
mais je ne sais pas comment je pourrais l'intégrer.
Toutes les recommandations seraient grandement appréciés. Sinon, c'est peut-être le moyen le plus rapide de faire ce que je veux?
EDIT Quelques points rapides (et excuses, je ne les ai pas mis dans le message d'origine):
- Les nombres et leur ordre (2, 3, 4, 3, 4, 3, 3, etc.) sont très importants, donc utiliser une solution telle que Générer des permutations à l'aide de LINQ n'aidera pas car les maximums dans chaque `` colonne '' sont différent
- Je ne suis pas mathématicien, alors je m'excuse si je n'utilise pas correctement les termes techniques comme «permutations» et «combinaisons» :)
- Je ne dois remplir toutes ces combinaisons à la fois - je ne peux pas saisir un ou l' autre , selon un indice
- L'utilisation
byte
est plus rapide que l'utilisationint
, je le garantis . Il est également bien meilleur sur l'utilisation de la mémoire d'avoir plus de 67 millions de tableaux d'octets plutôt que de - Mon objectif ultime ici est de rechercher une alternative plus rapide aux boucles imbriquées.
- J'ai envisagé d'utiliser la programmation parallèle, mais en raison de la nature itérative de ce que j'essaie d'accomplir, je n'ai pas pu trouver un moyen de le faire avec succès (même avec
ConcurrentBag
) - mais je suis heureux d'avoir tort :)
CONCLUSION
Caramiriel a fourni une bonne micro-optimisation qui réduit le temps des boucles, j'ai donc marqué cette réponse comme correcte. Eric a également mentionné qu'il est plus rapide de pré-attribuer la liste. Mais, à ce stade, il semble que les boucles imbriquées soient en fait le moyen le plus rapide possible de le faire (déprimant, je sais!).
Si vous voulez essayer exactement ce avec quoi j'essayais de comparer StopWatch
, optez pour 13 boucles comptant jusqu'à 4 dans chaque boucle - cela fait environ 67 millions de lignes dans la liste. Sur ma machine (i5-3320M 2,6 GHz), il faut environ 2,2 s pour faire la version optimisée.