上一篇文章提到了 通过 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. Object-C 点语法 -- 笔记

    第一种是经典方式, 第一种是点语法.

  2. 告诉你LTE-FDD与LTE-TDD的区别

    [PConline 技术分析]移动早在去年已经拿下了TD-LTE的4G牌照,而中国联通与中国电信的FDD-LTE的牌照在近日正式拿下,而对于4G网络,有多少真正了解呢?接下来笔者就为大家解释一下4G的 ...

  3. Mui实现退出登录

    document.getElementById("logout").addEventListener("tap",function(){ var btn=[&q ...

  4. javascript:运动框架

    function startMove(obj,json,fnEnd) { clearInterval(obj.timer);//清除定时器 obj.timer=setInterval(function ...

  5. nginx轮询配置详解

    nginx轮询配置详解... Nginx配置文件详细说明转载

  6. Linux shell 脚本中”2>&1″的含义解释

    脚本是:nohup /mnt/Nand3/H2000G  >/dev/null  2>&1 &   对于& 1 更准确的说应该是文件描述符 1,而1 一般代表的就是 ...

  7. oracle 复制一条记录只改变主键不写全部列名

    场景:表TEST中有C1,C2,C3...字段,其中C1为主键,先需要复制表TEST中一条(C1='1'的)记录,修改主键列C1和需要变更的列后,再插入到表TEST中. procedure P_TES ...

  8. CUICatalog: Invalid asset name supplied: (null)

    出现这个问题的根本原因是你调用了[UIImage imageNamed:name]这个方法 但是name = nil;所以报出该错误.   解决方法,在项目中搜索[UIImage imageNamed ...

  9. zepto源码研究 - zepto.js (zepto.init)

    简要:当我们用$()时,便会直接调用zepto.init 生成zepto对象,那zepto.init是如何根据不同类型的参数来生产指定对象呢? zepto.init = function(select ...

  10. 1.Tomcat配置

    1.启动 解压缩安装包后,点击startup.bat,保持控制台窗口开启 浏览器中输入http://localhost:8080 后看到启动界面则表示启动成功 点击shutdown.bat则关闭Tom ...