[ https://issues.apache.org/jira/browse/PDFBOX-2126?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14046964#comment-14046964 ]
Petr Slaby commented on PDFBOX-2126: ------------------------------------ I have already tried to replace the GeneralPath field by an Area field in PDGraphicsState myself, but then reverted it again. The problem is that Area is a slow and hungry beast. It seems that with a complex clipping path, it is better to give it back to garbage collector as soon as possible. Also, looking at the implementation of SunGraphics2D, the first thing that happens in clip() is that the shape is transformed using AffineTransform.createTransformedShape(). This is optimized (a little) for Path2D shapes, but not for Area. I have also tried using an alternative implementation of Area found at https://javagraphics.java.net/areax/. Compared to java.awt.Area, it is much faster and needs less memory when it comes to complex areas. It seems to be a little bit slower with simple rectangle areas. It has a modified BSD license that is fine for me, but I am personally not yet convinced whether it is worth having yet another third party library in the product. I am not sure whether it is compatible with the apache license, but for sure it is worth having a look at it just out of interest. It is amazing how a smart guy outperforms a big team at sun or oracle (albeit in a very small part of the library, of course). As for my original idea of applying the clipping path only if it has changed since being applied for the last time - your commit is a bit problematic for that. Because of the clippingPath.clone() in PDGraphicsState.clone() which is now necessary, I cannot use a simple comparison using lastClip == currentClip, I can probably solve it by having a counter in PDGraphcisState.intersectClippingPath() to keep track of how many times the clip has changed and what was the last change that was applied to Graphics2D. I will try to compare the performance of the code using the GeneralPath with the current one using Area again. I think that my code where I already tried that was quite similar to yours, but we will see. > Optimize clipping > ----------------- > > Key: PDFBOX-2126 > URL: https://issues.apache.org/jira/browse/PDFBOX-2126 > Project: PDFBox > Issue Type: Improvement > Components: Rendering > Affects Versions: 2.0.0 > Reporter: Petr Slaby > Attachments: ClipPath.1.patch, ClipPath.patch, example_010.pdf > > > As already stated in a TODO comment in PageDrawer, the call of > Graphics2D#setClip() is time and memory consuming. The attached patch > optimizes clipping by calling Graphics2D#setClip() only if the clipping path > has changed. The effect depends on the document, e.g. the attached one > renders in 10.5s without the optimization and in 5.5 seconds in the optimized > version. > The clipping has to be re-applied whenever the transform in Graphics2D > changes. This is not explicitly checked for, the implementation rather > depends on the cached value being reset manually. Currently this is only > needed at one place when processing annotations (AcroForms). Also, the > implementation relies upon the clipping path object stored in PDGraphicsState > to never change so that a comparison using == can be used. This works fine, > but needs a bit of awareness in future changes. To make the design more > clean, the clipping path could be made private to PDGraphcisState and thus > really "immutable" from outside. -- This message was sent by Atlassian JIRA (v6.2#6252)