Click here to Skip to main content
15,885,366 members
Articles / Programming Languages / C#

NParallel, A Small Parallel Execution Library

Rate me:
Please Sign up or sign in to vote.
4.06/5 (30 votes)
19 Dec 2007CPOL9 min read 68.5K   606   60  
A Simple Library which allows you to write asynchronous code easily, almost in a synchronous pattern.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Leaf.Parallel
{
    class TestClass1 : IDisposable
    {
        internal TestClass1() 
        {
            Console.WriteLine("Start Testing at {0}", DateTime.Now);
        }

        #region IDisposable Members

        public void Dispose()
        {
            Console.WriteLine("Testing done at {0}", DateTime.Now);
        }

        #endregion

        public int Calculate1(int input) 
        {
            Thread.Sleep(1000);
            return 100 * input;
        }

        public void Calculate2(int input) 
        {
            Thread.Sleep(1000);
            Console.WriteLine("Calculate Result for input {0} is {1}" , input , 100 * input);
        }

        //simple NParallel
        public void Test1() 
        {
            int input = 100;
            NParallel.Execute( ()=> 
            {
                Calculate2(input);
            }
            );

            NParallel.Execute<int>(delegate()
            {
                return Calculate1(input);
            }
            );

            for (int i = 0; i < 10; i++)
			{
                Thread.Sleep(100);
                Console.WriteLine("Tick {0}..." , i);
			}

            Console.WriteLine("Calculate Result for input {0} is {1}", input, 100 * input);
        }

        //simple For
        public void Test2() 
        {
            NParallel.For(0, 10, (int i) =>
                {
                    Thread.Sleep(100);
                    Console.WriteLine("Task {0} on Thread {1}", i, Thread.CurrentThread.ManagedThreadId);
                }
            );
        }

        // for with Result Merging
        public void Test3() 
        {
            float result2 = NParallel.For<float>(1, 120, 
                i =>{return 1.0f / i;} , 
                (i, j) => { return i + j; });

            Console.WriteLine("Result of 0 - 100 is {0}", result2);
        }

       // perf test: NParallel.For vs. for with result merging
        public void Test4()
        {
            int testSize = 8000000;
            int startTick = Environment.TickCount;
            double result2 = NParallel.For<double>(1, testSize,
                i => { return Math.Sin((i % 360) * 0.01);},
                (i, j) => { return i + j; });

            int usedTick = Environment.TickCount - startTick;
            Console.WriteLine("Result is {0} , UseTick {1} with NParallel 1", result2, usedTick);

            startTick = Environment.TickCount;
            //result2 = NParallel.For2<double>(1, testSize,
            //    i => { return Math.Sin((i % 360) * 0.01); },
            //    (i, j) => { return i + j; } ,0);
            //usedTick = Environment.TickCount - startTick;
            //Console.WriteLine("Result is {0} , UseTick {1} with NParallel 2", result2, usedTick);

            startTick = Environment.TickCount;
            result2 = 0.0f;
            for (int i = 1; i <= testSize; i++)
            {
                result2 += Math.Sin((i % 360) * 0.01);
            }

            usedTick = Environment.TickCount - startTick;
            Console.WriteLine("Result is {0} , UseTick {1} with Local", result2 , usedTick);

        }

        // perf test: NParallel For vs for without result merging
        public void Test5()
        {
            int testSize = 20000000;
            int startTick = Environment.TickCount;
            NParallel.For(1, testSize,
                i => { 
                    double result = 1.0 / i; 
                    if (i % 2000000 == 0) 
                        Console.WriteLine("{0}", result); }
                        );

            int usedTick = Environment.TickCount - startTick;
            Console.WriteLine();
            Console.WriteLine("UseTick {0} with NParallel", usedTick);

            startTick = Environment.TickCount;
            for (int i = 1; i <= testSize; ++i)
            {
                double resultX = 1.0 / i;
                if (i % 2000000 == 0) 
                    Console.WriteLine("{0}", resultX);
            }

            usedTick = Environment.TickCount - startTick;
            Console.WriteLine("UseTick {0} with Local", usedTick);

        }

        // perf; NParallel ForEach vs foreach without result merging
        public void Test6() 
        {
            int testSize = 20000000;
            int startTick = Environment.TickCount;
            NParallel.ForEach<int>(Enumerable.Range(1, testSize), i =>
                            {
                                double result = 1.0 / i;
                                if (i % 2000000 == 0)
                                    Console.WriteLine("{0}", result);
                            }
                        );

            int usedTick = Environment.TickCount - startTick;
            Console.WriteLine();
            Console.WriteLine("UseTick {0} with NParallel Foreach", usedTick);

            startTick = Environment.TickCount;
            foreach (int i in Enumerable.Range(1 , testSize))
            {
                double resultX = 1.0 / i;
                if (i % 2000000 == 0)
                    Console.WriteLine("{0}", resultX);
            }

            usedTick = Environment.TickCount - startTick;
            Console.WriteLine("UseTick {0} with Local", usedTick);
        }
        
        // perf; NParallel ForEach vs foreach with result merging
        public void Test7() 
        {
            int testSize = 8000000;
            int startTick = Environment.TickCount;
            double result = NParallel.ForEach<int, double>(Enumerable.Range(1, testSize), 
                i =>
                        {
                            return Math.Sin(Math.Sin((i % 360) * 0.01) * 360);
                        },
                (sumLocal, next) =>
                { 
                    return sumLocal + next; 
                } 
                , 0
                   );

            int usedTick = Environment.TickCount - startTick;
            Console.WriteLine();
            Console.WriteLine("Result {1} ,UseTick {0} with NParallel Foreach", usedTick , result);
            
            result = 0;
            startTick = Environment.TickCount;
            foreach (int i in Enumerable.Range(1, testSize))
            {
                double resultX = Math.Sin(Math.Sin((i % 360) * 0.01)*360);
                result = result + resultX;
            }

            usedTick = Environment.TickCount - startTick;
            Console.WriteLine("Result {1} , UseTick {0} with Local", usedTick , result);
        }


    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
China China
Leaf is a software developer based in ShangHai China.
My major programming languages are C#/C++.
I am very interested in distributed system design and rich client development.
Current I am working on NParallel.

Comments and Discussions