C# 多线程 Parallel.ForEach 和 ForEach 效率问题研究及理解

C# 多线程 Parallel.ForEach 和 ForEach 效率问题研究及理解最近要做一个大数据dataTable循环操作,开始发现运用foreach,进行大数据循环,并做了一些逻辑处理。在循环中耗费的时间过长。后来换成使用Parallel.ForEach来进行循环。一开始认为, 数据比较大时,Parallel.ForEach肯定比 ForEach效率高,后来发现,其实并不是这样。我用了1000万次循环测试:{CSDN:CODE:2601125}

大家好,又见面了,我是你们的朋友全栈君。

      最近要做一个大数据dataTable循环操作,开始发现 运用foreach,进行大数据循环,并做了一些逻辑处理。在循环中耗费的时间过长。后来换成使用Parallel.ForEach来进行循环。 一开始认为, 数据比较大时,Parallel.ForEach肯定比 ForEach效率高,后来发现,其实并不是这样。

我用了1000万次循环测试:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
         
            Stopwatch Watch1 = new Stopwatch();
            Watch1.Start();
            List<entityA> source = new List<entityA>();
            for (int i = 0; i < 10000000; i++)
            {
                source.Add(new entityA
                {
                    name = "悟空" + i,
                    sex = i % 2 == 0 ? "男" : "女",
                    age = i
                });
            }
            Watch1.Stop();

            Console.WriteLine("list循环插入耗时:" + Watch1.ElapsedMilliseconds);
            Stopwatch Watch2 = new Stopwatch();
            Watch2.Start();
            loop1(source);
            Watch2.Stop();
            Console.WriteLine("一般for循环耗时:" + Watch2.ElapsedMilliseconds);

            Stopwatch Watch3 = new Stopwatch();
            Watch3.Start();
            loop2(source);
            Watch3.Stop();
            Console.WriteLine("一般foreach循环耗时:" + Watch3.ElapsedMilliseconds);


            Stopwatch Watch4 = new Stopwatch();
            Watch4.Start();
            loop3(source);
            Watch4.Stop();
            Console.WriteLine("并行for循环耗时:" + Watch4.ElapsedMilliseconds);

            Stopwatch Watch5 = new Stopwatch();
            Watch5.Start();
            loop4(source);
            Watch5.Stop();
            Console.WriteLine("并行foreach循环耗时:" + Watch5.ElapsedMilliseconds);
            Console.ReadLine();
        }
        //普通的for循环
        static void loop1(List<entityA> source)
        {
            int count = source.Count();
            for (int i = 0; i < count; i++)
            {
                source[0].age= + 10;
                //System.Threading.Thread.Sleep(10);
            }
        }

        //普通的foreach循环
        static void loop2(List<entityA> source)
        {
            foreach (entityA item in source)
            {
                item.age =+ 10;
                //System.Threading.Thread.Sleep(10);
            }
        }

        //并行的for循环
        static void loop3(List<entityA> source)
        {
            int count = source.Count();
            Parallel.For(0, count, item =>
            {
                //source[count].age= source[count].age + 10;
                //System.Threading.Thread.Sleep(10);
            });
        }

        //并行的foreach循环
        static void loop4(List<entityA> source)
        {
            Parallel.ForEach(source, item =>
            {
                item.age = item.age + 10;
                //System.Threading.Thread.Sleep(10);
            });
        }
    }


    //简单的实体
    class entityA
    {
        public string name { set; get; }
        public string sex { set; get; }
        public int age { set; get; }
    }
}

运行结果:

C# 多线程 Parallel.ForEach 和 ForEach 效率问题研究及理解

结果居然是并行比一般的循环还耗时,但这是为什么呢?

这是因为循环体内执行的任务开销太小,仅仅是age+10 而已。微软的文章已经指出任务的开销大小对并行任务的影响。如果任务很小,那么由于并行管理的附加开销(任务分配,调度,同步等成本),可能并行执行并不是优化方案。这也是上述程序Foreach与For效率高出的原因。

基于这一点,我们对程序进行调整,循环1000次,每次里面线程sleep(10),这样我们试试。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
         
            Stopwatch Watch1 = new Stopwatch();
            Watch1.Start();
            List<entityA> source = new List<entityA>();
            for (int i = 0; i < 1000; i++)
            {
                source.Add(new entityA
                {
                    name = "悟空" + i,
                    sex = i % 2 == 0 ? "男" : "女",
                    age = i
                });
            }
            Watch1.Stop();

            Console.WriteLine("list循环插入耗时:" + Watch1.ElapsedMilliseconds);
            Stopwatch Watch2 = new Stopwatch();
            Watch2.Start();
            loop1(source);
            Watch2.Stop();
            Console.WriteLine("一般for循环耗时:" + Watch2.ElapsedMilliseconds);

            Stopwatch Watch3 = new Stopwatch();
            Watch3.Start();
            loop2(source);
            Watch3.Stop();
            Console.WriteLine("一般foreach循环耗时:" + Watch3.ElapsedMilliseconds);


            Stopwatch Watch4 = new Stopwatch();
            Watch4.Start();
            loop3(source);
            Watch4.Stop();
            Console.WriteLine("并行for循环耗时:" + Watch4.ElapsedMilliseconds);

            Stopwatch Watch5 = new Stopwatch();
            Watch5.Start();
            loop4(source);
            Watch5.Stop();
            Console.WriteLine("并行foreach循环耗时:" + Watch5.ElapsedMilliseconds);
            Console.ReadLine();
        }
        //普通的for循环
        static void loop1(List<entityA> source)
        {
            int count = source.Count();
            for (int i = 0; i < count; i++)
            {
                source[0].age= + 10;
                System.Threading.Thread.Sleep(10);
            }
        }

        //普通的foreach循环
        static void loop2(List<entityA> source)
        {
            foreach (entityA item in source)
            {
                item.age =+ 10;
                System.Threading.Thread.Sleep(10);
            }
        }

        //并行的for循环
        static void loop3(List<entityA> source)
        {
            int count = source.Count();
            Parallel.For(0, count, item =>
            {
                //source[count].age= source[count].age + 10;
                System.Threading.Thread.Sleep(10);
            });
        }

        //并行的foreach循环
        static void loop4(List<entityA> source)
        {
            Parallel.ForEach(source, item =>
            {
                item.age = item.age + 10;
                System.Threading.Thread.Sleep(10);
            });
        }
    }


    //简单的实体
    class entityA
    {
        public string name { set; get; }
        public string sex { set; get; }
        public int age { set; get; }
    }
}

执行结果:

C# 多线程 Parallel.ForEach 和 ForEach 效率问题研究及理解

效率一目了然。

这样的结果认证了我们上面的结论。当我们在循环中执行时间过长时,我们需要采用并行循环,效率较高。当时间过短,我们需要用foreach和for.

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

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/161789.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • EnableEventValidation=”false”「建议收藏」

    EnableEventValidation=”false”「建议收藏」出现这种原因在页面开头添加上EnableEventValidation=”false”

  • 单调队列-原理详解(deque实现)[通俗易懂]

    单调队列-原理详解(deque实现)[通俗易懂]一、单调队列的概念:单调队列,即单调递减或单调递增的队列。二、单调队列的性质:1.队列中的元素在原来的列表中的位置是由前往后的(随着循环顺序入队)。2.队列中元素的大小是单调递增或递减的。三、单调队列的特点:从队尾入列,队首或队尾出列。四、例题分析:那么单调队列用什么用呢?单调队列一般用于求区间内的最值问题。看几道题,理解上述内容:1.洛谷P1886…

  • NFS服务理解_什么才是最好的服务

    NFS服务理解_什么才是最好的服务概念NFS:NetworkFileSystem网络文件系统,基于内核的文件系统。通过使用NFS,用户和程序可以像访问本地文件一样访问远端系统上的文件,基于RPC(RemoteProcedu

  • 初学者python详细安装步骤_编程工具

    初学者python详细安装步骤_编程工具前言:随着人工智能的快速发展,python语言越来越受大家的欢迎,目前Python官网已经更新到了最新版Python3.7.2,这里详细介绍python安装,希望会对大家有所帮助,欢迎留言提问。

  • 小明加密通道进入_「成都全接触」最新!成都8条地铁进展来了!年底还有5条铁路、9条通道!…「建议收藏」

    小明加密通道进入_「成都全接触」最新!成都8条地铁进展来了!年底还有5条铁路、9条通道!…「建议收藏」友情提示:2020余额已不足四分之一大家关心的8条地铁线路也有了最新进度其中包括5条预计今年开通3条全新路线、2条机场快速线一起来看看有没有路过你家门口的(内含路线图)-10号线三期-最新进展:全线5个车站已全部打围,正在开展绿化迁移及管线迁改等前期工作,其中2个车站进行围护桩施工。2号线、10号线三期、17号线三线换乘车站——人民公园站已于10月15日首桩开钻。10号线三期工程北起人…

  • mt4平台如何下载_mt4交易平台

    mt4平台如何下载_mt4交易平台当前我们若要顺势进场交易,除了要选择一个好的交易平台,一个实用的投资软件也必不可少。虽然目前市面上流行着多种mt4平台,优质型的不少,但也不乏“山寨版”,后者多为不法平台为了恶意操纵显示的行情以坑骗投资者的资金而自主研发的,危害性极大。那mt4平台哪个比较好用更安全呢?务必要留意其下载渠道的正规性,通常,正规安全有监管的平台具有好的市场口碑,能提供更可靠的投资环境,其专有的mt4平台是为安全的下载渠道。投资者除了要知道mt4平台哪个比较好用更好之外,还应充分了解下载何种软件更利于我们顺畅交易。考虑到当前

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号