4

因此,我将 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 分钟。

4

2 回答 2

2

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

  • iTextSharp - 直接在 pdfwriter 上的内容生成器
    • 视窗 2008 64 位
    • NTFS 分区
    • 在处理过程中每秒合并大约 30 页
    • 关闭 pdfwriter 时最后的显着开销
    • 总共 25 页/秒
  • iTextSharp - PDF复制
    • 视窗 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();
    }
}
于 2012-12-05T15:02:59.647 回答
0

试试 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();
于 2012-06-22T17:31:29.477 回答