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

C#并行运算 Parallel.Invoke、Parallel.For、Parallel.Foreach性能测试及示例usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Numerics;namespaceSample3{classProgram{staticv

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)");
        }
    }
}

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

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();
        }
    }
}

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

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();
        }
    }
}

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

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();
        }
    }
}

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

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();
        }
    }
}

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/35599.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注