• 通过并行 提高批量审核PDF性能


      上一篇文章提到了 通过 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.大多数静态方法都是可同时从多个线程中调用。  但是,即使在这些情况下,所涉及到的同步也可能导致速度大幅减慢。

      

    工作点滴,持续提升

  • 相关阅读:
    Java并发编程笔记——技术点汇总
    Hello Blog
    shell变量
    认识bash这个shell
    使用myeclipse创建带注解的model实体类
    python List,切片的用法
    ignite从0到1的学习过程记录-第一篇:安装和体验
    安卓Service完全解析(中)
    安卓Service完全解析(上)
    JAVA之数组
  • 原文地址:https://www.cnblogs.com/bizprosdd/p/3519344.html
Copyright © 2020-2023  润新知