上一篇文章提到了 通过 iTextSharp 实现PDF 审核盖章 ,如果当需要一次审核大批量的PDF我们如何来提高程序的性能呢?

  下面我们通过并行计算来提升性能。

  

  首先是一个审核PDF的方法

 public class PDFManage
{
public string PDFApprove(string path)
{
//内部实现参见上一篇文字
       //返回是新的PDF路径 
}
}

  然后是普通的实现,我们拿到一个所有需要审核的PDF Path 集合 IList<string> pathLists

 PDFManage pdfManage = new PDFManage();
foreach (var item in pathLists)
{
pdfManage.PDFApprove(item);
}

  下面是并行的实现

  

Parallel.ForEach(pathLists, //可枚举的数据源
(itemPath, loopState) => //Action<TSource, ParallelLoopState> 的lambda表达式 形式 :将为每个迭代调用一次的委托
{
PDFManage pdfManage = new PDFManage();
pdfManage.PDFApprove(itemPath);
});

 

  为什么要把 PDFManage 实例放在每次迭代里面呢? 为了避免写入共享内存位子,每当多个线程同时访问时,都很有可能出现争用条件。  即使您可以使用锁来同步访问,同步开销也可能会对性能造成损害

  当我需要有拿到每一个审核后的新的PDF路径一个如何做呢?

  普通的实现我在这里就不写了,使用线程局部变量  Parallel.ForEach 循环来实现

  

IList<string> ApproveLists = new List<string>();

Parallel.ForEach(pathLists, //source 可枚举的数据源
() => { return new List<string>(); }, //用于返回每个任务的本地数据的初始状态的函数委托
(itemPath, loop, ApprovePaths) => //将为每个迭代调用一次的委托
{
PDFManage pdfManage = new PDFManage();
ApprovePaths.Add(pdfManage.PDFApprove(itemPath));
return ApprovePaths;
},
(finalResult) => //用于对每个任务的本地状态执行一个最终操作的委托(每个线程结束时最总会到这里来)
{
foreach (var item in ApproveLists)
{
finalResult.Add(item);
}
            //以原子操作的形式,将指定ApproveLists变量设置为指定finalResult值
Interlocked.Exchange(ref ApproveLists, finalResult);
});

使用并行的时候还需要注意: 不要假定并行始终速度更快,并行循环可能比顺序循环的运行速度慢。具有很少迭代和快速用户委托的并行循环未必会快很多。

计算机上的处理器数限制了并行化的优点。  在仅仅一个处理器上运行多个主要进行计算的线程时,速度并不会得到提升。

所以我们要加一些设定来优化一下

// 获取当前服务器处理器数量
int procCount = System.Environment.ProcessorCount; // 获取当前集合源的数量
int ListCount = pathLists.Count();

// 通过判断服务器的处理数量, 已经集合源的数量来决定是否需要进行并行计算。

总结一下使用并行:

  1.并行不一定更快,源的数量、委托的操作有关。

  2.并行时每个迭代调用内部不要有共享内存位子(简单说就是单线程和多线程争用条件的问题)

  3.大多数静态方法都是可同时从多个线程中调用。  但是,即使在这些情况下,所涉及到的同步也可能导致速度大幅减慢。

  

工作点滴,持续提升

通过并行 提高批量审核PDF性能的更多相关文章

  1. EF批量添加数据性能慢的问题的解决方案

    //EF批量添加数据性能慢的问题的解决方案 public ActionResult BatchAdd() { using (var db = new ToneRoad.CEA.DbContext.Db ...

  2. mysql 如何提高批量导入的速度

    mysql 如何提高批量导入的速度 最近一个项目测试,有几个mysql数据库的表数据记录达到了几十万条,在搭建测试环境 导入 测试数据时,十分慢.在网上搜索了一下,有下面一些方法可以加快mysql数据 ...

  3. 使用SQL-Server分区表功能提高数据库的读写性能

    首先祝大家新年快乐,身体健康,万事如意. 一般来说一个系统最先出现瓶颈的点很可能是数据库.比如我们的生产系统并发量很高在跑一段时间后,数据库中某些表的数据量会越来越大.海量的数据会严重影响数据库的读写 ...

  4. 使用内存虚拟硬盘 提高ArcGIS server并发性能的一种方法

    1 问题提出 1.1 概述 提高ArcGIS server并发性能的方法很多,本文讨论在用户硬件足够强大的情况下(主要是内存足够大),使用内存模拟硬盘来提高数据的读取效率,以达到提高ArcGIS se ...

  5. MySQL批量SQL插入性能优化

    对于一些数据量较大的系统,数据库面临的问题除了查询效率低下,还有就是数据入库时间长.特别像报表系统,每天花费在数据导入上的时间可能会长达几个小时或十几个小时之久.因此,优化数据库插入性能是很有意义的. ...

  6. 提高 Linux 上 socket 性能

      http://www.cnblogs.com/luxf/archive/2010/06/13/1757662.html 基于Linux的Socket网络编程的性能优化   1 引言    随着In ...

  7. 使用Zend OpCache 提高 PHP 5.5+ 性能

    使用Zend OpCache 提高 PHP 5.5+ 性能 作者:admin | 时间:February 28, 2015 | 分类:Linux | 评论:1 评论 PHP 5.5 以后内建了 OpC ...

  8. 使用异步 I/O 大大提高应用程序的性能

    使用异步 I/O 大大提高应用程序的性能 学习何时以及如何使用 POSIX AIO API Linux® 中最常用的输入/输出(I/O)模型是同步 I/O.在这个模型中,当请求发出之后,应用程序就会阻 ...

  9. 走向DBA[MSSQL篇] - 从SQL语句的角度提高数据库的访问性能(转)

    最近公司来一个非常虎的DBA,10几年的经验,这里就称之为蔡老师吧,在征得我们蔡老同意的前提下 ,我们来分享一下蔡老给我们带来的宝贵财富,欢迎其他的DBA来拍砖.  目录 1.什么是执行计划?执行计划 ...

随机推荐

  1. Target runtime Apache Tomcat v6.0 is not defined. phyy Unknown Faceted Project Problem

    Description Resource Path Location TypeTarget runtime Apache Tomcat v6.0 is not defined. phyy Unknow ...

  2. Linux 系统运行级别

    Linux运行级别从0-6,共7个.  0:关机.不能将系统缺省运行级别设置为0,否则无法启动.  1:单用户模式,只允许root用户对系统进行维护.  2:多用户模式,但不能使用NFS(相当于Win ...

  3. 更加详细的Log4net的配置

    请转到周金桥的文章 http://blog.csdn.net/zhoufoxcn/article/details/6029021

  4. javascript基础之javascript的存在形式和js代码块在页面中的存放位置

    1.存在形式 文件 如: <script src='js/jc.js'></script> 前页面 <script type='text/javascript'>a ...

  5. DOM基础之“寻找”子节点

    今天学习了JS中的DOM的内容,虽然小菜的理解不深,但希望能够记录下来,慢慢一点一点的进步,有更深的理解了,再回来补充. 首先,关于DOM的概念: 1.概念:DOM = document(文档)Obj ...

  6. redux-simple 简化版的redux

    作为react的粉丝,当然要吐槽一下react组件通信问题.react的单向数据流是组件通信的一大阻碍,只允许父组件向子组件传值,子组件向父组件传值只能通过父组件向子组件传递回调函数实现.如果在深层次 ...

  7. "float: left;" div 不换行显示

    <div id='p'> <div id='c1'> </div> <div id='c2'> </div> <div id='c3' ...

  8. epoll 中EPOLLIN 和 EPOLLOUT

    epoll主要是事件回调运行的,我们使用socket的时候主要使用两个事件 EPOLLOUT事件:EPOLLOUT事件只有在连接时触发一次,表示可写,其他时候想要触发,那你要先准备好下面条件:1.某次 ...

  9. div+css的叫法是不正确的

    为什么国人将这种布局标准页面的方法叫做DIV+CSS? 因为第一个将这种技术引进中国的人,对这门技术理解不够透彻,单纯从代码上辨别过去的页面布局方法和现在流行的页面布局方法,认为过去布局页面用的是Ta ...

  10. redis常见命令

    一.介绍 1.Redis是什么 REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统.Redis提供了一些丰富 ...