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因爲有資源競爭的情況,所以串行不一定會慢於並行

所以處理業務時需要根據具體問題具體分析,就像鞋穿着舒適纔好

 

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