4

だから私は100002ページのPDFファイルを取り、それらをiTextSharpで1つにマージしています。

これは私がやっていることのいくつかの緩いコードです:

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);
    }
}

ボトルネックが2か所にある可能性がある場所を理解しようとしています。私はいくつかのパフォーマンステストを実行しましたが、最も遅いプロセスはPdfReaderを使用して各ファイルを自然に読み取り、ファイルを保存しているdisposeは、usingPdfWriterブロックから呼び出されます。

このプロセスでは、16コアすべてで約25%の使用率が得られています。SATA 7.2k rpmドライブの代わりにソリッドステートドライブを試しましたが、ほぼ同じ速度です。

このプロセスをどのようにスピードアップできますか?コンピューター間の読み取り速度がさらに遅くなるため、タスクを分散することはできません。別の言語やライブラリに変更したり、この下位レベルを作成したりすることを意味する場合でも、このプロセスを現在よりもはるかに速く実行する必要があります。現在、マージには約10分かかります。

4

2 に答える 2

2

だから私は最終的にこれを解決しました。以下は、成功したアプローチのコードを使用したパフォーマンス結果です。3 つの論文テストすべてで同じマシンを使用しました。

  • iTextSharp - pdfwriter で直接コンテンツ ビルダー
    • Windows 2008 64 ビット
    • NTFS パーティション
    • 処理中に毎秒約 30 ページをマージします
    • 最後に pdfwriter を終了する際の大きなオーバーヘッド
    • 全体で毎秒 25 ページ
  • iTextSharp - PDFコピー
    • 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();
    }
}
于 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 に答える