2010-08-12 5 views
3

est-il possible que je peux optimiser ceci:Optimisation: Comment optimiser la concaténation Linq des collections? C#

public static IEnumerable<IEnumerable<int>> GenerateCombinedPatterns 
    (IEnumerable<IEnumerable<int>> patterns1, 
    IEnumerable<IEnumerable<int>> patterns2) 
{ 
    return patterns1 
      .Join(patterns2, p1key => 1, p2key => 1, (p1, p2) => p1.Concat(p2)) 
      .Where(r => r.Sum() <= stockLen) 
      .AsParallel() 
     as IEnumerable<IEnumerable<int>>; 
} 
+0

Vous pouvez ignorer la partie "as IEnumerable >". C'est implicite. –

+0

Les données proviennent-elles de la base de données? –

+0

Non, ce n'est pas une opération sur une collection de choses importées d'un fichier. J'ai vérifié les autres domaines .. L'importation et l'exportation de fichiers ne prennent pas de temps .. et même la génération de modèles .. mais ce bloc de code semble ralentir tout. – Sam

Répondre

2

Si vous êtes à la recherche pour chaque combinaison, utilisez plutôt SelectMany, généralement effectué avec de multiples « de » clauses:

return from p1 in patterns1 
     from p2 in patterns2 
     let combination = p1.Concat(p2) 
     where combination.Sum() <= stockLen 
     select combination; 

C'est sans aucun parallélisme si ... en fonction des collections attendues, Je probablement juste paralléliser à un niveau, par exemple

return from p1 in patterns1.AsParallel() 
     from p2 in patterns2 
     let combination = p1.Concat(p2) 
     where combination.Sum() <= stockLen 
     select combination; 

Notez qu'il n'y a aucune garantie quant à l'ordre dans lequel les résultats sortent au-dessus - vous auriez besoin de ruser si vous vouliez la commande originale.

1

Aucun point à faire le parallèle de requête à la fin. Mise à jour: Jon avait raison, ma solution initiale était incorrecte et s'avère que ma solution corrigée était essentiellement la même que la sienne.

public static IEnumerable<IEnumerable<int>> GenerateCombinedPatterns 
    (IEnumerable<IEnumerable<int>> patterns1, 
    IEnumerable<IEnumerable<int>> patterns2) 
{ 
    var parallel1 = patterns1.AsParallel(); 
    return parallel1.SelectMany(p1 => patterns2.Select(p2 => p1.Concat(p2))) 
     .Where(r => r.Sum() <= stockLen); 
} 
+0

Je ne crois pas que cela fasse la même chose que l'original. –

+0

Ouais je regarde ce Join() et au second coup d'oeil, peut-être était un aplatissement à la place qui était ma conjecture initiale. –

+0

si j'ajoute.AsParallel alors l'application semble prendre environ 6 fois le temps qu'il faut si elle n'est pas utilisée. – Sam