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中并行开发优化的更多相关文章

  1. 使用ThinkPHP开发中MySQL性能优化的最佳21条经验

    使用ThinkPHP开发中MySQL性能优化的最佳21条经验讲解,目前,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更 ...

  2. 在 Android开发中,性能优化策略十分重要

    在 Android开发中,性能优化策略十分重要本文主要讲解性能优化中的布局优化,希望你们会喜欢.目录 示意图 1. 影响的性能 布局性能的好坏 主要影响 :Android应用中的页面显示速度 2. 如 ...

  3. .NET下的并行开发

    并行开发一直是程序员在开发项目中遇到的一道坎,但为了迎合硬件的升级,面对高端多核的处理器,并行编程势在必行.在.NET平台下的开发支持并行模式,下面用一个实际项目说明并行的高效率和神奇之处. 在优化中 ...

  4. 8天玩转并行开发——第八天 用VS性能向导解剖你的程序

    原文 8天玩转并行开发——第八天 用VS性能向导解剖你的程序 最后一篇,我们来说说vs的“性能向导",通常我们调试程序的性能一般会使用Stopwatch,如果希望更加系统的了解程序,我们就需 ...

  5. 【SQL系列】深入浅出数据仓库中SQL性能优化之Hive篇

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[SQL系列]深入浅出数据仓库中SQL性能优化之 ...

  6. 并行开发 8.用VS性能向导解剖你的程序

    原文:8天玩转并行开发——第八天 用VS性能向导解剖你的程序 最后一篇,我们来说说vs的“性能向导",通常我们调试程序的性能一般会使用Stopwatch,如果希望更加系统的了解程序,我们就需 ...

  7. [.net 面向对象程序设计进阶] (24) 团队开发利器(三)使用SVN多分支并行开发(下)

    [.net 面向对象程序设计进阶] (24) 团队开发利器(三)使用SVN多分支并行开发(下) 本篇导读: 接上篇继续介绍SVN的高级功能,即使用分支并行开发.随着需求的不断变更,新功能的增加.特别是 ...

  8. .NET下的并行开发(案例代码)

    以下主要是通过一个报表处理程序来说明并行开发的方式.对于数据冲突和共享,可以通过对象数组解决.设计到并行的核心代码已用红色标出.在并行程序的处理上,需要把原来串行的子公司变成一个一个类的对象,让所有的 ...

  9. 【翻译】CEDEC2014跨世代多平台并行开发PS4版如龙维新开发的一年

    本篇PPT讲述的是如龙4的开发过程中,集中在PS3和PS4并行开发中所遇到和解决的一些问题.如64位指针,DX9向DX11移植API的问题,以及在PS4上使用并行渲染在1080P下让FPS达到60等. ...

随机推荐

  1. 分享知识-快乐自己:Hibernate 中 get() 和 load()、sava、update、savaOrUpdate、merge,不同之处及执行原理?

    1):Hibernate 中 get()  和 load() 有什么不同之处? 1)Hibernate的 get方法,会确认一下该id对应的数据是否存在,首先在session缓存中查找,然后在缓存中查 ...

  2. (转)select、poll、epoll之间的区别总结[整理]

    select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作.但select ...

  3. linux 进程学习笔记-进程跟踪

    进程跟踪 long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data); Linux用ptrace来进行进 ...

  4. LeetCode 426. Convert Binary Search Tree to Sorted Doubly Linked List

    原题链接在这里:https://leetcode.com/problems/convert-binary-search-tree-to-sorted-doubly-linked-list/ 题目: C ...

  5. vue之axios请求数据本地json

    写给自己的话:静态的json文件要记得放在static文件夹下,想打自己 1.下载插件 npm install axios --save 2.在main.js下引用axios import axios ...

  6. java定时器,留着用

    说明:该定时器作用是 设定定时器首次执行的时间firstTime和执行间隔period,如firstTime=2015-3-25 9:00:00,period=24小时,若程序启动时,已经超过firs ...

  7. JSON 生成 C# Model

    http://www.cnblogs.com/tianqiq/p/4309791.html

  8. [hdu3853]LOOPS(概率dp)

    题意:迷宫是一个R*C的布局,每个格子中给出停留在原地,往右走一个,往下走一格的概率,起点在(1,1),终点在(R,C),每走一格消耗两点能量,求出最后所需要的能量期望. 解题关键:概率dp反向求期望 ...

  9. CodeForces 484A Bits(水题)

    A. Bits time limit per test 1 second memory limit per test 256 megabytes input standard input output ...

  10. SpringBoot使用拦截器无效

    附上代码: public class WendaWebConfiguration extends WebMvcConfigurerAdapter { @Autowired PassportInterc ...