sabato 15 dicembre 2012

Easy Parallelism in .NET ? PLINQ !

come parallelizzare facilmente delle ricerche all'interno di una lista ? usando PLinQ cos'è ?
immaginate una ricerca su una lista semplice cosi come di seguito :

var customers = new[] {
 new Customer { ID = 1,  FirstName = "Sandeep"  , LastName = "Ramani" },
 new Customer { ID = 2,  FirstName = "Dharmik"  , LastName = "Chotaliya" },
 new Customer { ID = 3,  FirstName = "Nisar"    ,  LastName = "Kalia" } ,
 new Customer { ID = 4,  FirstName = "Ravi"     , LastName = "Mapara" } ,
 new Customer { ID = 5,  FirstName = "Hardik"   , LastName = "Mistry" }
 new Customer { ID = 6,  FirstName = "Sandy"    , LastName = "Ramani" },
 new Customer { ID = 7,  FirstName = "Jigar"    , LastName = "Shah" },
 new Customer { ID = 8,  FirstName = "Kaushal"  , LastName = "Parik" } ,
 new Customer { ID = 9,  FirstName = "Abhishek" , LastName = "Swarnker" } ,
 new Customer { ID = 10, FirstName = "Sanket"   , LastName = "Patel" }
 new Customer { ID = 11, FirstName = "Dinesh"   , LastName = "Prajapati" },
 new Customer { ID = 12, FirstName = "Jayesh"   , LastName = "Patel" },
 new Customer { ID = 13, FirstName = "Nimesh"   , LastName = "Mishra" } ,
 new Customer { ID = 14, FirstName = "Shiva"    , LastName = "Reddy" } ,
 new Customer { ID = 15, FirstName = "Jasmin"   , LastName = "Malviya" }
 new Customer { ID = 16, FirstName = "Haresh"   , LastName = "Bhanderi" },
 new Customer { ID = 17, FirstName = "Ankit"    , LastName = "Ramani" },
 new Customer { ID = 18, FirstName = "Sanket"   , LastName = "Shah" } ,
 new Customer { ID = 19, FirstName = "Amit"     , LastName = "Shah" } ,
 new Customer { ID = 20, FirstName = "Nilesh"   , LastName = "Soni" }       };

  List<Customer> result = new List<Customer>();
 foreach( Customer c in customers )
  if ( c.FirstName.StartWith("San") )
   result.add(c) ;
Come parallalelizzare semplicemente ed in maniera efficente questa ricerca ? 
semplicemente usando PLinQ e sostituendo il ciclo in questo modo : 


var results = from c in customers.AsParallel()
  where c.FirstName.StartsWith("San")
  select c;


Con la semplice aggiunta del metodo di estensione AsParallel(), il runtime .NET automaticamente parallelizza l'operazione in più nuclei. 

Limitazioni :
PLINQ funziona solo contro collezioni locali. Questo significa che se si sta utilizzando il provider LINQ sopra dati remoti, ad esempio LINQ to SQL o ADO.NET Entity Framework, allora non sei fortunato per questa versione. Poiché PLINQ divide la collection in più partizioni e li esegue in parallelo, i risultati che si otterrebbero da una query PLINQ non sarà nello stesso ordine dei risultati che si otterrebbero da una query LINQ eseguita o da un approccio tradizionale.

 Tuttavia, si può aggirare questo introducendo il metodo AsOrdered() nella tua query, che costringerà a un ordinamento specifico nei vostri risultati.




var results = from c in customers.AsParallel().AsOrdered()
  where c.FirstName.StartsWith("San")
  select c;



Tieni presente, tuttavia, che inserendo AsOrdered()per insiemi di grandi dimensioni, puoi perdere in termini di performance i guadagni di parallelizzazione ottenuti.

Nessun commento:

Posta un commento