【问题标题】:iTextSharp PDFWriter bottleneckiTextSharp PDFWriter 瓶颈
【发布时间】:2012-06-21 23:30:39
【问题描述】:

所以我要使用 10000 个 2 页 pdf 文件并将它们与 iTextSharp 合并为一个。

这是我正在做的一些松散的代码:

Document document = new Document();
using(PdfWriter writer = PdfWriter.GetInstance(document, new FileStream("merged.pdf", FileMode.Create)))
{  

    PdfContentByte cb = writer.DirectContent;
    PdfReader reader = null;
    foreach(string thisFile in files)
    {
       reader = new PdfReader(thisFile);
       var page1 = writer.GetImportedPage(reader, 1);
       var page2 = writer.GetImportedPage(reader, 2);
       cb.AddTemplate(page1, 1f, 0, 0, 1f, 0, 0);
       cb.AddTemplate(page2, 1f, 0, 0, 1f, 0, 0);
    }
}

我试图了解瓶颈可能在两个地方。我进行了一些性能测试,最慢的进程自然是使用 PdfReader 读取每个文件以及保存文件的处置,它从 using PdfWriter 块中调用。

我在此过程中的所有 16 个内核上的利用率约为 25%。我尝试了固态驱动器而不是我的 SATA 7.2k rpm 驱动器,它的速度几乎完全相同。

我怎样才能加快这个过程?没有分配任务,因为计算机之间的读取速度会更慢。即使这意味着更改为另一种语言、库或编写这个较低级别的代码,我也需要比现在更快地完成这个过程。现在合并大约需要 10 分钟。

【问题讨论】:

    标签: performance pdf itextsharp


    【解决方案1】:

    所以我终于解决了这个问题。以下是我使用以下获胜方法的代码的性能结果: 我在这三个测试中都使用了同一台机器

    • iTextSharp - 直接在 pdfwriter 上的内容生成器
      • Windows 2008 64 位
      • NTFS 分区
      • 在处理过程中每秒合并大约 30 页
      • 关闭 pdfwriter 时最后的显着开销
      • 每秒 25 页
    • iTextSharp - PDFCopy
      • Windows 2008 64 位
      • NTFS 分区
      • 将输出写入磁盘而不是内存,因此最后没有开销
      • 每秒 40 页
    • iText (java) - PDFCopy(完全相同的代码,只是移植到 java)
      • Ubuntu 12.04 64位服务器版
      • EXT3 分区(即将尝试 ext4)
      • 还在处理过程中将输出写入磁盘
      • 每秒 250 页

    还没有试图弄清楚为什么相同的代码在 Ubuntu 上的 java 中运行得更快,但我会接受它。一般来说,我在这个函数之外定义了所有主要变量,因为它在这个过程中被调用了 36000 次。

    public void addPage(String inputPdf, String barcodeText, String pageTitle)
    {
        try
        {
            //read in the pdf
            reader = new PdfReader(inputPdf);
    
            //all pdfs must have 2 pages (front and back). 
            //set to throw an out of bounds error if not. caught up stream
            for (int i = 1; i <= Math.Min(reader.NumberOfPages,2); i++)
            {
                //import the page from source pdf
                copiedPage = copyPdf.GetImportedPage(reader, i);
    
                // add the page to the new document
                copyPdf.AddPage(copiedPage);
            }
    
            //cleanup this page, keeps a big memory leak away
            copyPdf.FreeReader(reader);
            copyPdf.Flush();
    
        }
        finally
        {
            reader.Close();
        }
    }
    

    【讨论】:

    • +1 获取有关FreeReader 的提示。不过,我不太确定您是否需要调用Flush,这可能会导致一些额外的开销,因为所有缓冲区都必须写入磁盘。
    【解决方案2】:

    试试 PdfSmartCopy。不确定它是否更快。

    Document document = new Document();
    using(PdfWriter writer = new PdfSmartCopy(document, new FileStream("merged.pdf", FileMode.Create)))
    {  
        document.Open();
        PdfReader reader = null;
        foreach(string thisFile in files)
        {
           reader = new PdfReader(thisFile);
           ((PdfSmartCopy)writer).AddPage(writer.GetImportedPage(reader , 1));
           ((PdfSmartCopy)writer).AddPage(writer.GetImportedPage(reader , 2));
        }
    
        if(reader != null)
        {
           reader.Close();
        }
    }
    document.Close();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-20
      • 2014-03-29
      相关资源
      最近更新 更多