Best performance for adding text via x,y position

We are trying to upgrade from Aspose.Pdf 8.3.1.0 to the latest version 19.1.0.0 due to restrictions/bugs in the older version that affect functionality we now need to implement. We are currently using a trial license for the new version while we convert our code to make sure it will work and have completed most of our development work but have run into a couple of issues. I will post separate threads for each so that they can be responded to individually.

This post is in reference to performance when adding textfragments to a PDF.

In the old version we could create a 500 page document in less than a minute, but in the newer one it takes almost 15 minutes and creates a file that is twice as big! These files contain only lines and text. All of the text components are added as small text segments via X, Y position, imagine an excel spreadsheet formatted as a PDF where each cell is printed separately.

Our old code for adding text was (fPdfSection was used once per page with the IsNewPage flag set to true):

        Text pdfText = new Text(fPrintedMessage);
        pdfText.Margin.Left = 0.0F;
        pdfText.Margin.Top = 0.0F;
        pdfText.Margin.Right = 0.0F;
        pdfText.Margin.Bottom = 0.0F;
        SetFont(pdfText.TextInfo, (printFont == null ? fCurrentFont : (MitasFonts)printFont));

        pdfText.Left = GetColumnPosition(fColumn);
        pdfText.Top = GetRowPosition(fRow);

        pdfText.PositioningType = PositioningType.PageRelative;
        fPdfSection.Paragraphs.Add(pdfText);

Our current code:

        fRow = (printRow == null ? fRow : (double)printRow);
        fColumn = (printColumn == null ? fColumn : (double)printColumn);
        Aspose.Pdf.Text.TextFragment pdfText = new Aspose.Pdf.Text.TextFragment(fPrintedMessage);
        pdfText.IsInLineParagraph = true;
        pdfText.Margin.Left = 0.0F;
        pdfText.Margin.Top = 0.0F;
        pdfText.Margin.Right = 0.0F;
        pdfText.Margin.Bottom = 0.0F;
        SetFont(pdfText.TextState, (printFont == null ? fCurrentFont : (MitasFonts)printFont));

        double xIndent = GetColumnPosition(fColumn) - adjustLeft;
        double yIndent = GetPrintableTopPosition() - GetRowPosition(fRow); //Position is indexed based on lower left corner so we need to invert the y coordinate                    
        yIndent -= pdfText.Rectangle.Height; //Since we are printing from the bottom up, we need to adjust by the height of the box itself
        xIndent += GetPrintableLeftPosition(); //Add the margin since we are absolute position
        pdfText.Position = new Aspose.Pdf.Text.Position(xIndent, yIndent);

         Aspose.Pdf.Text.TextBuilder tb = new Aspose.Pdf.Text.TextBuilder(fPdfPage);
         tb.AppendText(pdfText);

Note: Code that is similar, such as font color/opacity/rotation/alignment have been removed from both code segments to clean that code up. Out of that list, the current example 500 page document only used the alignment function of this removed code segments.

Can you please tell us if there is a better way to add text via X,Y position in the newer DOM environment? We can not possibly roll out the new version with such a large performance hit in place.

@TheMitasGroup

Thank you for contacting support.

You are following the right approach to add text on specific position. However, would you please share SSCCE code or sample application which does not include any undeclared variables and may be used to reproduce the scenario in our environment. We will investigate further to help you out.

Here is a chunk of code that adds 750 elements to each of 100 pages which took over 7.5 minutes. The number of elements is consistent with the number of elements we regularly put on our outputs. As mentioned, in the (much) older Aspose version we were able to generate about 500 pages in less than a minute. so this is a significant difference.

Aspose.Pdf.Document myPdf = new Aspose.Pdf.Document();
myPdf.PageInfo.Width = Aspose.Pdf.PageSize.PageLetter.Width;
myPdf.PageInfo.Height = Aspose.Pdf.PageSize.PageLetter.Height;
myPdf.PageInfo.Margin.Top = 36;
myPdf.PageInfo.Margin.Bottom = 36;
myPdf.PageInfo.Margin.Left = 24;
myPdf.PageInfo.Margin.Right = 24;

string lastElapsed;
int pageCount = 100;
int lineCount = 75;
int colCount = 10;
bool printTimeInFirstColumn = true;
System.Diagnostics.Stopwatch swTotal = new System.Diagnostics.Stopwatch();
swTotal.Start();
for (int pageNumber = 1; pageNumber <= pageCount; pageNumber++)
{
    Aspose.Pdf.Page myPage = myPdf.Pages.Add();
    myPage.SetPageSize(Aspose.Pdf.PageSize.PageLetter.Width, Aspose.Pdf.PageSize.PageLetter.Height);
    myPage.PageInfo.Margin = myPage.PageInfo.Margin;

    for (int lineNumber = 1; lineNumber <= lineCount; lineNumber++)
    {
        for (int colNumber = 1; colNumber <= colCount; colNumber++)
        {
            if (printTimeInFirstColumn && colNumber == 1)
            {
                TimeSpan elapsed = swTotal.Elapsed;
                lastElapsed = $"{elapsed.Minutes:00}:{elapsed.Seconds:00}.{elapsed.Milliseconds:000}";
            }
            else
            {
                lastElapsed = $"{pageNumber:000}/{lineNumber:00}/{colNumber:00}";
            }

            //Aspose.Pdf.Text.TextFragment pdfText = new Aspose.Pdf.Text.TextFragment($"Col{colNumber}Line{lineNumber}");
            Aspose.Pdf.Text.TextFragment pdfText = new Aspose.Pdf.Text.TextFragment(lastElapsed);
            pdfText.IsInLineParagraph = true;

            double lineWidth = pdfText.Rectangle.Width;

            pdfText.Margin.Left = 0.0F;
            pdfText.Margin.Top = 0.0F;
            pdfText.Margin.Right = 0.0F;
            pdfText.Margin.Bottom = 0.0F;
            pdfText.Position = new Aspose.Pdf.Text.Position(24 + ((colNumber - 1) * 60), 792 - (24 + (lineNumber * 10)));

            Aspose.Pdf.Text.TextBuilder tb = new Aspose.Pdf.Text.TextBuilder(myPage);
            tb.AppendText(pdfText);

            if (pageNumber == pageCount && lineNumber == lineCount && colNumber == colCount)
            {
                pdfText = new Aspose.Pdf.Text.TextFragment("Total time for Add Text method: " + swTotal.Elapsed);
                pdfText.IsInLineParagraph = true;

                pdfText.Margin.Left = 0.0F;
                pdfText.Margin.Top = 0.0F;
                pdfText.Margin.Right = 0.0F;
                pdfText.Margin.Bottom = 0.0F;
                pdfText.Position = new Aspose.Pdf.Text.Position(0, 0);

                tb = new Aspose.Pdf.Text.TextBuilder(myPage);
                tb.AppendText(pdfText);
            }
        }
    }
}
swTotal.Stop();
myPdf.Save($"C:\\Temp\\TextTiming_{pageCount}.pdf");

TextTiming_100.pdf (322.0 KB)
TextTiming_10.pdf (33.4 KB)

I have also attached a 10 page version which took over 47 seconds.

@TheMitasGroup

Thank you for sharing requested details.

We have been able to notice slower performance and have logged a ticket with ID PDFNET-46044 in our issue management system for further investigation and resolution. The ticket ID has been linked with this thread so that you will receive notification as soon as the ticket is resolved.

We are sorry for the inconvenience.

Any updates on this??

@TheMitasGroup

Thank you for getting back to us.

We are afraid this ticket is currently pending for investigations and may take few more months. However, we have recorded your concerns and will notify you as soon as it is resolved. We appreciate your patience in this regard.

Hello,

We have recently purchase a licence for Aspose.PDF just to find out that our document processing needs are not met because of this issue. The memory footprint of using tables, paragraphs for our processing is reaching few GB’s and using this approach we’ve managed to kept it down to below 100MB however timing in generating the document is extremely long - 15 minutes in our case compared to seconds with Tables, Paragraphs.

Can you please provide a timeline regarding this fix, otherwise we’ll have to go for a refund and find alternative software to fit our needs.

Thanks,
Fouad

@fouadinfo

Thank you for contacting support.

Please note that we offer free 30 days temporary license prior purchase, in order to allow evaluation of APIs in their full capacity. About PDFNET-46044, we are afraid it is still pending owing to previously logged and critical tickets and ETA is not available at the moment. However, we have recorded your concerns and will let you know once any update will be available.

Hi,

We are in the process of upgrading from Aspose.pdf 9.2.1 to 21.9 and it would appear that we have similar implementations and timing concerns as noted above. Can you confirm PDFNET-46044 is still outstanding?

@PeteWK

I regret to share that at present the issue is still unresolved. We request for your patience and will share the good news with you as soon as the issue will be fixed.

The issues you have found earlier (filed as PDFNET-46044) have been fixed in Aspose.PDF for .NET 21.12.