C#并行运算 Parallel.Invoke、Parallel.For、Parallel.Foreach性能测试及示例

来源:互联网 发布:bp网络和卷积神经网络 编辑:程序博客网 时间:2024/05/21 07:55
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Numerics;namespace Sample3{    class Program    {        static void Main(string[] args)        {            //准确获取运行时间            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();            Console.ForegroundColor = ConsoleColor.Yellow;            Console.WriteLine("一般串行开始.....");            sw.Start();            Calc100();            Calc100();            Calc100();            sw.Stop();            Console.WriteLine("总耗时 = " + sw.ElapsedMilliseconds + "(ms)");            Console.ForegroundColor = ConsoleColor.Cyan;            Console.WriteLine("并行处理开始.....");            sw.Restart();            sw.Start();            Parallel.Invoke(Calc100, Calc100, Calc100);            sw.Stop();            Console.WriteLine("总耗时= " + sw.ElapsedMilliseconds + "(ms)");            Console.ReadLine();        }        static void Calc100()        {            int n = 1000000;            BigInteger b = new BigInteger(long.MaxValue);            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();            sw.Start();            for (var k = 1; k <= n; k++)            {                BigInteger b2 = k * b;            }            sw.Stop();            Console.WriteLine("calc " + n + " times bigint multiply cost time " + sw.ElapsedMilliseconds + "(ms)");        }    }}

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Numerics;namespace Sample3{    class Program    {        static void Main(string[] args)        {            /*             * Parallel.For这个方法和For循环的功能相似,执行并行循环             * 并行如果访问全局变量,会出现资源争夺,大多数时间消耗在了资源等待上,效率不如For             */            System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();            stopWatch.Start();            for (int i = 0; i < 10000; i++)            {                for (int j = 0; j < 60000; j++)                {                    int sum = 0;                    sum += i;                }            }            stopWatch.Stop();            Console.WriteLine("NormalFor run " + stopWatch.ElapsedMilliseconds + " ms.");            stopWatch.Reset();            stopWatch.Start();            Parallel.For(0, 10000, item =>            {                for (int j = 0; j < 60000; j++)                {                    int sum = 0;                    sum += item;                }            });            stopWatch.Stop();            Console.WriteLine("ParallelFor run " + stopWatch.ElapsedMilliseconds + " ms.");            Console.ReadLine();        }    }}

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Numerics;namespace Sample3{    class Program    {        static void Main(string[] args)        {            System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();            stopWatch.Start();            List<int> list = new List<int>();            Parallel.For(0, 10000, (i, state) =>            {                for (int j = 0; j < 60000; j++)                {                    if (j == 1000)                    {                        state.Stop(); //Parallel中途退出循环                        return;  //不要使用break,会出错                    }                    else                    {                        double t = j * 1000 + 200/1.3; //做些计算                        list.Add(j);                    }                }            });            stopWatch.Stop();            Console.WriteLine("ParallelFor run " + stopWatch.ElapsedMilliseconds + " ms.");            Console.WriteLine("list counts " + list.Count);            Console.ReadLine();        }    }}

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Numerics;using System.Threading;using System.Collections.Concurrent;namespace Sample3{    class Program    {        static void Main(string[] args)        {            List<int> list = new List<int>();            Parallel.For(0, 10000, item =>            {                list.Add(item);            });            //结果不对?这是因为List<T>是非线程安全集合,意思就是说所有的线程都可以修改他的值            Console.WriteLine("List's count is {0}", list.Count());            /*正确做法                         * 线程安全集合,在System.Collections.Concurrent命名空间中,             * 看一下ConcurrentBag<T>泛型集合,其用法和List<T>类似             * 例如Dictionary的ConcurrentDictionary            */            ConcurrentBag<int> list2 = new ConcurrentBag<int>();            Parallel.For(0, 10000, item =>            {                list2.Add(item);            });            Console.WriteLine("ConcurrentBag's count is {0}", list2.Count());            Console.ReadLine();        }    }}

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Numerics;using System.Threading;using System.Collections.Concurrent;namespace Sample3{    class Program    {        static void Main(string[] args)        {            /*             * 第一个想到的同步方法就是使用lock或者Monitor,             * 然而在4.0 之后微软给我们提供了另一把利器——spinLock,             * 它比重量级别的Monitor具有更小的性能开销,它的用法跟Monitor很相似             * Parallel.For用起来方便,但是在实际开发中还是尽量少用,因为它的不可控性太高             * 容易出现意想不到的错误             */            SpinLock slock = new SpinLock(false);            long sum1 = 0;            long sum2 = 0;            Parallel.For(0, 100000, i =>            {                sum1 += i;            });            Parallel.For(0, 100000, i =>            {                bool lockTaken = false;                try                {                    slock.Enter(ref lockTaken);                    sum2 += i;                }                finally                {                    if (lockTaken)                        slock.Exit(false);                }            });            Console.WriteLine("结果1的值为:{0}", sum1);            Console.WriteLine("结果2的值为:{0}", sum2);            Console.Read();        }    }}

原创粉丝点击