NET中并行开发优化
让我们考虑一个简单的编程挑战:对大数组中的所有元素求和。现在可以通过使用并行性来轻松优化这一点,特别是对于具有数千或数百万个元素的巨大阵列,还有理由认为,并行处理时间应该与常规时间除以CPU核心数一样多。事实证明,这一壮举并不容易实现。我将向您展示几种并行执行此操作的方法,它们如何改善或降低性能以及以某种方式影响性能的所有细节。
简单的循环方法

private const int ITEMS = 500000;
private int[] arr = null; public ArrayC()
{
arr = new int[ITEMS];
var rnd = new Random();
for (int i = 0; i < ITEMS; i++)
{
arr[i] = rnd.Next(1000);
}
} public long ForLocalArr()
{
long total = 0;
for (int i = 0; i < ITEMS; i++)
{
total += int.Parse(arr[i].ToString());
} return total;
} public long ForeachLocalArr()
{
long total = 0;
foreach (var item in arr)
{
total += int.Parse(item.ToString());
} return total;
}

只需要迭代循环就可以计算出结果,超级简单,这里没有用直接相加求出结果,原因是直接求出结果,发现每次基本的运行都比并行快,但是实际上,并行处理没有那么简单,所以这里的加法就简单的处理下total += int.Parse(arr[i].ToString())。现在,让我们尝试用并行性来打败数组迭代吧。
首次尝试

private object _lock = new object(); public long ThreadPoolWithLock()
{
long total = 0;
int threads = 8;
var partSize = ITEMS / threads;
Task[] tasks = new Task[threads];
for (int iThread = 0; iThread < threads; iThread++)
{
var localThread = iThread;
tasks[localThread] = Task.Run(() =>
{
for (int j = localThread * partSize; j < (localThread + 1) * partSize; j++)
{
lock (_lock)
{
total += arr[j];
}
}
});
} Task.WaitAll(tasks);
return total;
}

请注意,您必须使用localThread变量来“保存”该iThread时间点的值。否则,它将是一个随着for循环前进而变化的捕获变量。当数据最后打的时候并行已经比普通的快了,但是发现快的不多,说明还可以优化
再次优化

public long ThreadPoolWithLock2()
{
long total = 0;
int threads = 8;
var partSize = ITEMS / threads;
Task[] tasks = new Task[threads];
for (int iThread = 0; iThread < threads; iThread++)
{
var localThread = iThread;
tasks[localThread] = Task.Run(() =>
{
long temp = 0;
for (int j = localThread * partSize; j < (localThread + 1) * partSize; j++)
{
temp += int.Parse(arr[j].ToString());
} lock (_lock)
{
total += temp;
}
});
} Task.WaitAll(tasks);
return total;
}

增加设置临时变量,减少lock次数,发现运行效果已经有质的提高,提高了几倍。忽然想起,有个Parallel.For的方法,研究性能是否可以更快。
Parallel.For优化

public long ParallelForWithLock()
{
long total = 0;
int parts = 8;
int partSize = ITEMS / parts;
var parallel = Parallel.For(0, parts, new ParallelOptions(), (iter) =>
{
long temp = 0;
for (int j = iter * partSize; j < (iter + 1) * partSize; j++)
{
temp += int.Parse(arr[j].ToString());
} lock (_lock)
{
total += temp;
}
});
return total;
}

运行结果比普通迭代快,但是没有ThreadPool快,但是觉得Parallel.For还可以继续优化,也许可以更快
Parallel.For继续优化

public long ParallelForWithLock2()
{
long total = 0;
int parts = 8;
int partSize = ITEMS / parts;
var parallel = Parallel.For(0, parts,
localInit: () => 0L, // Initializes the "localTotal"
body: (iter, state, localTotal) =>
{
for (int j = iter * partSize; j < (iter + 1) * partSize; j++)
{
localTotal += int.Parse(arr[j].ToString());
} return localTotal;
},
localFinally: (localTotal) => { total += localTotal; });
return total;
}

运行效果已经很快,和ThreadPool优化过的差不多,有些时候更快
结论和总结
并行化优化肯定可以提高性能,但是这取决于很多因素,每个案例都应该进行测量和检查。
当各种线程需要通过某种锁定机制相互依赖时,性能会显着降低。
50万数据运行结果
NET中并行开发优化的更多相关文章
- 使用ThinkPHP开发中MySQL性能优化的最佳21条经验
使用ThinkPHP开发中MySQL性能优化的最佳21条经验讲解,目前,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更 ...
- 在 Android开发中,性能优化策略十分重要
在 Android开发中,性能优化策略十分重要本文主要讲解性能优化中的布局优化,希望你们会喜欢.目录 示意图 1. 影响的性能 布局性能的好坏 主要影响 :Android应用中的页面显示速度 2. 如 ...
- .NET下的并行开发
并行开发一直是程序员在开发项目中遇到的一道坎,但为了迎合硬件的升级,面对高端多核的处理器,并行编程势在必行.在.NET平台下的开发支持并行模式,下面用一个实际项目说明并行的高效率和神奇之处. 在优化中 ...
- 8天玩转并行开发——第八天 用VS性能向导解剖你的程序
原文 8天玩转并行开发——第八天 用VS性能向导解剖你的程序 最后一篇,我们来说说vs的“性能向导",通常我们调试程序的性能一般会使用Stopwatch,如果希望更加系统的了解程序,我们就需 ...
- 【SQL系列】深入浅出数据仓库中SQL性能优化之Hive篇
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[SQL系列]深入浅出数据仓库中SQL性能优化之 ...
- 并行开发 8.用VS性能向导解剖你的程序
原文:8天玩转并行开发——第八天 用VS性能向导解剖你的程序 最后一篇,我们来说说vs的“性能向导",通常我们调试程序的性能一般会使用Stopwatch,如果希望更加系统的了解程序,我们就需 ...
- [.net 面向对象程序设计进阶] (24) 团队开发利器(三)使用SVN多分支并行开发(下)
[.net 面向对象程序设计进阶] (24) 团队开发利器(三)使用SVN多分支并行开发(下) 本篇导读: 接上篇继续介绍SVN的高级功能,即使用分支并行开发.随着需求的不断变更,新功能的增加.特别是 ...
- .NET下的并行开发(案例代码)
以下主要是通过一个报表处理程序来说明并行开发的方式.对于数据冲突和共享,可以通过对象数组解决.设计到并行的核心代码已用红色标出.在并行程序的处理上,需要把原来串行的子公司变成一个一个类的对象,让所有的 ...
- 【翻译】CEDEC2014跨世代多平台并行开发PS4版如龙维新开发的一年
本篇PPT讲述的是如龙4的开发过程中,集中在PS3和PS4并行开发中所遇到和解决的一些问题.如64位指针,DX9向DX11移植API的问题,以及在PS4上使用并行渲染在1080P下让FPS达到60等. ...
随机推荐
- 发现eclipse红叉,查看markers发现Target runtime Apache Tomcat v8.0 is not defined
导入以前的项目(Markers中注意查看,就在console选项卡旁边),报以下错误,但不影响操作: Faceted Project Problem Target runtime Apa ...
- leetcode 130 Surrounded Regions(BFS)
Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. A region is captured ...
- ACM学习历程—HDU5410 CRB and His Birthday(动态规划)
Problem Description Today is CRB's birthday. His mom decided to buy many presents for her lovely son ...
- Jenkins持续集成环境搭建
1部署Jenkins Jenkins部署很简单,只需建立一个新应用,将Jenkins的war包部署进去,再分配好权限就可以了. 1.1创建应用 建立一个新Nginx应用:jenkins.com 1.2 ...
- 解决CentOS 7安装zabbix 3.0 无法启动zabbix-server的问题[segfault at 18 ip 00007f78842b4bd0 sp 00007fff1995a818 error 4 in libpthread-2.17.so[7f78842ab000+16000]]
解决CentOS 7安装zabbix 3.0 无法启动zabbix-server的问题 [root@localhost sbin]# service zabbix-server start Redir ...
- AI-Info-Micron-Insight:将您的游戏技能变成一份工作
ylbtech-AI-Info-Micron-Insight:将您的游戏技能变成一份工作 1.返回顶部 1. 将您的游戏技能变成一份工作 听起来不现实? 一位来自著名商学院的教授不这么认为.他认为,金 ...
- MODBUS ASCII和RTU两种模式的区别、优缺点
转自:http://blog.sina.com.cn/s/blog_89f286ad0102uzju.html 下表是MODBUS ASCII协议和RTU协议的比较: 协议 开始标记 结束标记 校验 ...
- winform 控件合集2
http://www.cnblogs.com/peterzb/archive/2009/06/18/1505424.html 包含自定义绘制的ListBox, 带拖动,图片显示, 内嵌其它控件, 打印 ...
- linux下使用c判断文件夹是否为空的小程序
自己写了一个 判断文件夹是否为空的小代码 //文件夹操作相关的函数的帮助$: man 3 readdir #include <stdio.h> #include <sys/types ...
- Ajax的调试错误信息的输出
error: function(xhr, status, error) { console.log(xhr); console.log(status); console.log(error); }