<![endif]–>
Hi Aspose team!
Recently I did a lot of performance testing of Aspose.Pdf 5.2 and found a serious bottleneck related to hyperlinks.
So the generated document is
based on 6k data records which are rendered to approximately 2000 pages (40-70MB),
also is contains ToC, Index and embedded hyperlinks which provide just another
way to navigate the content.
After numerous tests, it appears
that Aspose.Pdf is not able to handle huge amounts of hyperlinks, e.g.: index
consists of approx. 100 pages and contains 6k+ hyperlinks linked to different
paragraphs. The code which creates PDF DOM runs pretty fast, but delay happens during
Pdf.Save(memoryStream) method. Here are details:
6k data set, no hyperlinks
- Data access and DOM generation – 1min
- Aspose.Pdf save to stream – 1min
Same but index hyperlinks on
- Data access and DOM generation – 1min
- Aspose.Pdf save to stream – 10min (+9min with ToC/embedded hyperlinks on)
Here is the way I add hyperlinks
to text segments:
private void AddIndexItem(Section section, string titleText, Rect frame, IEnumerable<SectionLink> sectionLinks)
{
const string indexSep = ", ";
var root = section.GetRoot();
var itemStyle = new TextInfo
{
FontName = “Arial”,
FontSize =10,
Color = new Color("Black"),
IsUnicode = true,
};
// Assemble and measure segments: title, indexes and elipsis
var titleWidth = TextMeasure.GetStringWidth(titleText, itemStyle);
var indexesText = string.Join(indexSep,
sectionLinks.Select(sl => sl.Index.ToString()));
var indexesWidth = TextMeasure.GetStringWidth(indexesText, itemStyle);
var ellipsisWidth = TextMeasure.GetStringWidth(ChartDocument.Elipsis, itemStyle);
var ellipsisCount = (int)Math.Truncate((frame.Width - titleWidth - indexesWidth) / ellipsisWidth);
var ellipsisText = ellipsisCount > 0
? new string(ChartDocument.Elipsis[0], ellipsisCount) : "";
// Add title with a link to first index item
var firstLink = new Hyperlink
{
LinkType = HyperlinkType.Local,
TargetID = sectionLinks.First().SectionId,
};
var firstIndexItem = new Text(section)
{
Segments =
{
new Segment(titleText)
{
IsSymbolReplaceable = false,
Hyperlink = firstLink,
},
new Segment(ellipsisText)
{
Hyperlink = firstLink
},
},
PositioningType = PositioningType.ParagraphRelative,
ReferenceParagraphID = root.ID,
Left = frame.Left.ToFloat(),
Top = frame.Top.ToFloat() + 1,
TextInfo = itemStyle,
WrapLines = 1,
};
section.Paragraphs.Add(firstIndexItem);
// Add indexes with the corresponding links
var indexItems = new Text(section)
{
PositioningType = PositioningType.ParagraphRelative,
ReferenceParagraphID = root.ID,
Left = (frame.Right - indexesWidth).ToFloat(),
Top = frame.Top.ToFloat() + 1,
TextInfo = itemStyle,
WrapLines = 1,
};
sectionLinks.ToList()
.ForEach(sl =>
{
indexItems.Segments.Add(); // walkaround 1
indexItems.Segments.Add(
new Segment(
sl.Index == sectionLinks.Last().Index
? sl.Index.ToString()
: string.Concat(sl.Index, indexSep))
{
TextInfo = { FontName = “Arial” }, // walkaround 2
Hyperlink =
{
LinkType = HyperlinkType.Local,
TargetID = sl.SectionId,
}
});
});
section.Paragraphs.Add(indexItems);
}
private struct SectionLink
{
public int Index;
public string SectionId;
}
Any suggestions or ideas how to
avoid the performance degradation? Ideally I wish hyperlinks overhead to be 30
sec max instead of 9 min. The issue is urgent, because product going to release
in a few months
Thanks in advance,
Alex