Võrdleme LINQ ja PLINQ jõudlust

14.01.2010  |  Gunnar

Visual Studio 2010 Neid õnnetuid, kes .NET Framework 4.0 ettekandele ei jõudnud, püüan natukenegi rõõmustada sellega, et avaldan ühe näite toimunud ettekandelt. Panen pildid ka juurde ja seletan veidike koodi lahti. Teemaks LINQ ja PLINQ ja loodetavasti pole siintoodu põhjal raske ise katset korrata.

Materjalid
powerpoint2007_16x16 Presentatsioon
folder16x16 Lähtekood
 

Viimaseks näiteks ettekandel oli PLINQ ehk Parallel LINQ. .NET Framework 4.0 saab kenasti hakkama ka mitme protsessori või arvutustuuma kasutamisega ja selle jaoks on loodud spetsiaalsed laiendusmeetodid. LINQ päringud saab mitme arvutustuuma peale laiendada lihtsasti – kutsu vaid päritava kollektsiooni küljest laiendusmeetodi AsParallel().

Ja loomulikult – PLINQ pole hõbekuul iga haige päringu raviks. Samuti on tal omad piirangud, millega tuleb arvestada ning alati on mõistlik päringuid proovida ka klassikaliste LINQ lausetega ja võrrelda mõlemi jõudlust.

PLINQ ei ole tegelikult uus. Juba mõnda aega on teda arendatud eraldi projektina. .NET Framework pere täisõiguslikuks liikmeks saab ta alates versioonist 4.0.

PLINQ Demo

Ettekandes kasutatud PLINQ näide pärineb kellegi blogi kandest Using PLINQ to Speed Up CPU Bound Operations - Demo. Lähtekoodi arhiivis on projekti nimeks PLINQ Demo. Meid huvitav kood asub klassis PrimeNumberDemo.cs. Tegemist on algarvude leidmisega tavalise ForEach ja paralleelse ForEach laiendusmeetodi abil. Neist esimene kuulub LINQ ja teine PLINQ koosseisu.

Demo töötab järgmiselt. List nimega upperLimits sisaldab arve, milleni vastava järjekorranumbriga ringil algarvude otsimisega minnakse. Mina täiendasin originaali sellega, et lisasin listi viimaseks elemendiks 150000. Kaugemale polnud vähemasti mõtet minu masina peal minna. Kes soovib läbi viia peenemaid mõõtmisi võib selle listi täita ka programmiliselt enda jaoks sobiva suurusega sammudega.

Päringute jõudluse demonstreerimine

PrimeNumberDemo.cs sisaldab järgmist koodijuppi.

//Run the demos for both parallel and sequential runs
long sequentialTime = RunSequentialTest(numbersToCheck);
long parallelTime = RunParallelTest(numbersToCheck);

Tavalise ForEach proovimiseks muuda toodud koodijuppi selliselt.

//Run the demos for both parallel and sequential runs
long sequentialTime = RunSequentialTest(numbersToCheck);
long parallelTime = 10000; //RunParallelTest(numbersToCheck);

Paralleelse ForEach proovimiseks muude koodijupp selliseks.

//Run the demos for both parallel and sequential runs
long sequentialTime = 0; //RunSequentialTest(numbersToCheck);
long parallelTime = RunParallelTest(numbersToCheck);

Kui aegu tahad võrrelda, siis lase näide käima originaalkujul ilma igasuguste muudatusteta. Käivitamisel kuvatakse ekraanile kenasti tsüklite läbiviimiseks kulunud ajad mõlemal juhul ja see annab hea võimaluse nende võrdlemiseks.

Task Manager annab hea võimaluse toimuvat pildis jälgida. Järgneval ekraanpaugul on toodud ära tavaline ja paralleelne ForEach eraldi käivitatuna (nende mõlema käivitamisel ei anna Task Manager toimuvast kuigi head ülevaadet).

ForEach ja paralleelne ForEach pildis

Pilte vaadates näeme, et tavalise ForEach korral kulub aega arvutustele rohkem, sest ühte tuuma ei kasutata. Vasakpoolsel pildil on näha, et paralleelne ForEach toimib kiiremini, sest kasutusel on mõlemad tuumad. Graafikuna välja tuues oli tulemus järgmine.

LINQ ja PLINQ võrdlus
LINQ ja PLINQ võrdlus. x-teljel on arvuvahemike ülempiirid, mille seest
algarve leitakse. y-teljel on ülesande täitmiseks kulunud aeg millisekundites.
 

Graafikult on näha, et alguses ei ole erilist vahet kumba kasutada. Kui millisekundeid lähemalt võrrelda, siis selgub, et alguses on LINQ jõudlus isegi parem. Ühel hetkel tekib aga murdepunkt, millest alates LINQ jääb oluliselt aeglasemaks. Minul tuli antud näite korral see punkt 150.000 peal ning selleks hetkeks andis PLINQ kaks korda paremad tulemused kui LINQ.

Ettekandel sai seda kõike muidugi lives jälgida minu ohtra mulina saatel. Keda graafikud lähemalt huvitavad, siis on viitsinud neid välja joonistada Stefan Cruysberghs oma blogi artiklis Performance comparison with Parallel Extensions .NET 3.5.

Kommenteeri

sulge
Saada link e-postiga

© DT 2012 | Creative Commons Attribution-Noncommercial 3.0 License | WordPress