I’ve been playing alot with reflection lately to analyze code and apply metrics on it. Unfortunately on large projects this means dealing with hundreds of thousands of objects representing classes, methods and the like. When parsing them I hit a wall because the code would run for hours before spitting out the results. I started looking for optimizations and one of the choices was to replace for cycles with linq queries. That added some benefits but still not enough.
What I saw was that my quad core processor was utilizing a single core and of course I started thinking threads but I am lazy. Luckily I remembered about PLinq. I haven’t used it until now so I did a little bit of research. Well research is a harsh word, more like reading a bit on how to use it and I found that is actually easy to switch a query from Linq to PLinq. At the most basic level you just have to select not from your collection but from your collection marked for paralelization. You can do that by saying myCollection.AsParallel(). Well ain’t that easy?!
Just so as you can see the importance of this, my processing went down from 5 hours to 1 hour.
You can see below some code that you can use to check the performance. Just be sure to run it on a multi core machine :)

            Random r = new Random((int)DateTime.Now.Subtract(DateTime.Today).Ticks);
            List<int> list = new List<int>();
            for (int i = 0; i < 30000000; i++)
            {
                list.Add(r.Next());
            }

            DateTime t1 = DateTime.Now;

            var paraleled = (from i in list.AsParallel()
                             where CheckPrime(i)
                             select i).ToList();

            DateTime t2 = DateTime.Now;

            var unparaleled = (from i in list
                               where CheckPrime(i)
                               select i).ToList();

            DateTime t3 = DateTime.Now;

            Console.WriteLine("Paralel linq select : " + t2.Subtract(t1).TotalMilliseconds);
            Console.WriteLine("Normal linq select : " + t3.Subtract(t2).TotalMilliseconds);

One thing to highlight here is that the “slow” processing is emulated by a CheckPrime method which unfortunately is not as slow as I would want. If you want to see real benefits, modify to call a more intensive method there.

Leave a Reply