C#并行计算 Parallel.Invoke 和简单串行性能对比

1.为了直观,选用三个方法三个方法代码逻辑一致,计算次数一致

using System;
using System.Threading.Tasks;

namespace AppCode
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

            Console.ForegroundColor = ConsoleColor.Red;
            stopwatch.Start();
            Call();
            Call1();
            Call2();
            Console.WriteLine("串行总用   "+stopwatch.ElapsedMilliseconds + "ms");


            stopwatch = new System.Diagnostics.Stopwatch();

            Console.ForegroundColor = ConsoleColor.Green;
            stopwatch.Start();
            Parallel.Invoke(Call, Call1, Call2);
            Console.WriteLine("并行总用   " + stopwatch.ElapsedMilliseconds + "ms");

            Console.Read();
        }

        private static void Call()
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

            stopwatch.Start();
            int temp = int.MaxValue / 10;
            string value = "";
            for (int i = 0; i < temp; i++)
            {
                value = i.ToString();
            }
            Console.WriteLine("第一次,循环" + temp + "次" + stopwatch.ElapsedMilliseconds + "ms");
        }

        private static void Call1()
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

            stopwatch.Start();
            int temp = int.MaxValue / 10000;
            string value = "";
            for (int i = 0; i < temp; i++)
            {
                value = i.ToString();
            }
            Console.WriteLine("第二次,循环" + temp + "次" + stopwatch.ElapsedMilliseconds + "ms");
        }

        private static void Call2()
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

            stopwatch.Start();
            int temp = int.MaxValue / 1000;
            string value = "";
            for (int i = 0; i < temp; i++)
            {
                value = i.ToString();
            }
            Console.WriteLine("第三次,循环" + temp + "次" + stopwatch.ElapsedMilliseconds + "ms");
        }
    }
}

 

 由下图可知

1.串行就是按顺序执行,并行不按顺序执行

2.并行相比于串行耗时少

3.并行相比于串行对cpu的利用率较高

 

2.为了直观,选用三个方法三个方法代码逻辑一致,计算次数一致,但计算次数相比第一次都减少 1000倍

using System;
using System.Threading.Tasks;

namespace AppCode
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

            Console.ForegroundColor = ConsoleColor.Red;
            stopwatch.Start();
            Call();
            Call1();
            Call2();
            Console.WriteLine("串行总用   "+stopwatch.ElapsedMilliseconds + "ms");


            stopwatch = new System.Diagnostics.Stopwatch();

            Console.ForegroundColor = ConsoleColor.Green;
            stopwatch.Start();
            Parallel.Invoke(Call, Call1, Call2);
            Console.WriteLine("并行总用   " + stopwatch.ElapsedMilliseconds + "ms");

            Console.Read();
        }

        private static void Call()
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

            stopwatch.Start();
            int temp = int.MaxValue / 1000;
            string value = "";
            for (int i = 0; i < temp; i++)
            {
                value = i.ToString();
            }
            Console.WriteLine("第一次,循环" + temp + "次" + stopwatch.ElapsedMilliseconds + "ms");
        }

        private static void Call1()
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

            stopwatch.Start();
            int temp = int.MaxValue / 1000;
            string value = "";
            for (int i = 0; i < temp; i++)
            {
                value = i.ToString();
            }
            Console.WriteLine("第二次,循环" + temp + "次" + stopwatch.ElapsedMilliseconds + "ms");
        }

        private static void Call2()
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

            stopwatch.Start();
            int temp = int.MaxValue / 1000;
            string value = "";
            for (int i = 0; i < temp; i++)
            {
                value = i.ToString();
            }
            Console.WriteLine("第三次,循环" + temp + "次" + stopwatch.ElapsedMilliseconds + "ms");
        }
    }
}

 由下图可知

1.串行就是按顺序执行,并行不按顺序执行

2.并行相比于串行耗时少

3.并行和串行耗时较少不进行cpu比较,截图没这么快,有兴趣的可以自己试,根据经验并行cpu应该比串行利用率高

 

3.为了直观,选用三个方法三个方法代码逻辑一致,计算次数不一致,计算次数分别减少100倍、1000倍、10000倍

using System;
using System.Threading.Tasks;

namespace AppCode
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

            Console.ForegroundColor = ConsoleColor.Red;
            stopwatch.Start();
            Call();
            Call1();
            Call2();
            Console.WriteLine("串行总用   "+stopwatch.ElapsedMilliseconds + "ms");


            stopwatch = new System.Diagnostics.Stopwatch();

            Console.ForegroundColor = ConsoleColor.Green;
            stopwatch.Start();
            Parallel.Invoke(Call, Call1, Call2);
            Console.WriteLine("并行总用   " + stopwatch.ElapsedMilliseconds + "ms");

            Console.Read();
        }

        private static void Call()
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

            stopwatch.Start();
            int temp = int.MaxValue / 100;
            string value = "";
            for (int i = 0; i < temp; i++)
            {
                value = i.ToString();
            }
            Console.WriteLine("第一次,循环" + temp + "次" + stopwatch.ElapsedMilliseconds + "ms");
        }

        private static void Call1()
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

            stopwatch.Start();
            int temp = int.MaxValue / 1000;
            string value = "";
            for (int i = 0; i < temp; i++)
            {
                value = i.ToString();
            }
            Console.WriteLine("第二次,循环" + temp + "次" + stopwatch.ElapsedMilliseconds + "ms");
        }

        private static void Call2()
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

            stopwatch.Start();
            int temp = int.MaxValue / 10000;
            string value = "";
            for (int i = 0; i < temp; i++)
            {
                value = i.ToString();
            }
            Console.WriteLine("第三次,循环" + temp + "次" + stopwatch.ElapsedMilliseconds + "ms");
        }
    }
}

 

 由下图可知

结论和第二个测试一致

 

以上是不同时处理一个变量的结果,现在再试一次同时处理一个变量会是什么情况,还会快吗?

4.访问同一变量,为了直观,选用三个方法三个方法代码逻辑一致,计算次数不一致,计算次数分别减少100倍、1000倍、10000倍,在代码中加入“锁” 

                lock (obj)
                {
                    lvalue += i;
                }

using System;
using System.Threading.Tasks;

namespace AppCode
{
    class Program
    {
        static object obj = new object();
        static long lvalue = 0;
        static void Main(string[] args)
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

            Console.ForegroundColor = ConsoleColor.Red;
            stopwatch.Start();
            Call();
            Call1();
            Call2();
            Console.WriteLine("串行总用   "+stopwatch.ElapsedMilliseconds + "ms" + " lvalue="+ lvalue);

            lvalue = 0;
            stopwatch = new System.Diagnostics.Stopwatch();

            Console.ForegroundColor = ConsoleColor.Green;
            stopwatch.Start();
            Parallel.Invoke(Call, Call1, Call2);
            Console.WriteLine("并行总用   " + stopwatch.ElapsedMilliseconds + "ms" + " lvalue=" + lvalue);

            Console.Read();
        }

        private static void Call()
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

            stopwatch.Start();
            int temp = int.MaxValue / 100;

            for (int i = 0; i < temp; i++)
            {
                lock (obj)
                {
                    lvalue += i;
                }
            }
            Console.WriteLine("第一次,循环" + temp + "次" + stopwatch.ElapsedMilliseconds + "ms");
        }

        private static void Call1()
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

            stopwatch.Start();
            int temp = int.MaxValue / 1000;
            string value = "";
            for (int i = 0; i < temp; i++)
            {
                lock (obj)
                {
                    lvalue += i;
                }
            }
            Console.WriteLine("第二次,循环" + temp + "次" + stopwatch.ElapsedMilliseconds + "ms");
        }

        private static void Call2()
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

            stopwatch.Start();
            int temp = int.MaxValue / 10000;
            string value = "";
            for (int i = 0; i < temp; i++)
            {
                lock (obj)
                {
                    lvalue += i;
                }
            }
            Console.WriteLine("第三次,循环" + temp + "次" + stopwatch.ElapsedMilliseconds + "ms");
        }
    }
}

如下图,如果访问同一变量并行还没有串行快

 

5.结论

5.1不访问同一变量的情况下

5.1.1在不访问同一变量时,系统资源无限的情况下(也就是内存、cpu无限的情况下)或者电脑资源可以同时处理多个任务的情况下,串行会比并行慢

5.1.2串行是有序的,并行是无须的

5.2访问同一变量的情况下

5.2.1因为有资源竞争的情况,所以串行不一定会慢于并行

所以处理业务时需要根据具体问题具体分析,就像鞋穿着舒适才好

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章