Jeremias,

To be honest I was just guessing and hoping it would be better, I would have expected some improvement.. but alas I've just done some testing and its actually slower.. so I think I'll scrap this idea and we'll stick with plain old BufferedOutputStream. Thanks for the feedback and the link too :).

Adrian.

Jeremias Maerki wrote:
So what will happen if there's no FileChannel available (for example, in
a servlet)? Will the AFP output stop working?

In additional to what Max wrote (preserving compatibility with output
targets that are not nio-compatible), I'd say that bit of potential
performance improvement is totally irrelevant in the command-line after
all the class loading and JIT. It might help in a server-environment,
though. But did you make any measurements that indicate that the
performance would indeed be considerably better? Or are you just
guessing/hoping?

http://www.cs.cmu.edu/~jch/java/rules.html
Steve McConnell's "Code Complete" comes to mind, too.


On 10.11.2008 13:13:03 Adrian Cumiskey wrote:
Max,

I understand what you are saying, but I am trying not to change too much code or FOP's API with this change. Currently the BufferedOutputStream is passed as an OutputStream reference all the way down the calling chain during rendering.

So although your suggestion would result in a much neater result, changing the OutputStream references to some sort of custom OutputSource would be quite a big change to the FOP API and may break existing FOP integrations. This is why I was just proposing the subclassing BufferedOutputStream to expose the getChannel() method for the cases where new I/O would be useful.

Adrian.

Max Berger wrote:
Adrian,

when doing this you need to be very careful that either the
BufferedOutputStream OR the FileChannel methods are used. If you start
mixing both you will get very strange effects.  So for safety I would
prefer to pass either a stream or a channel to a renderer, but not both.

Also, you need to make sure that the AFP renderer work if just a Stream
is available - this could be needed in cases where the output is stdout
(although I don't know if this would be a common use case).

Maybe a wrapper class similar to the idea of org.xml.sax.InputSource
would do the trick?

Max

Adrian Cumiskey schrieb:
When FOP is started in Main.startFOP() a java.io.BufferedOutputStream is
instantiated and wrapped around an instantiated
java.io.FileOutputStream.  By wrapping the initial
java.io.FileOutputStream with a java.io.BufferedOutputStream, FOP is not
able to potentially make use of the nio FileChannel stuff which could
provide more efficient final output writing (using modern operating
system caching) [1].

This would especially be the case for AFP writing as output is initially
written in two parts for memory saving reasons, one outputstream for
document resources and one for the actual document.  On completion of
rendering the document is appended to the end of the document resources
outputstream.

So I am proposing the introduction and instantiation of a
FileChannelAccessibleBufferedOutputStream which extends
java.io.BufferedOutputStream in Main.startFOP().  It will expose the
getChannel() method of java.io.FileOutputStream.  I have included the
small code changes I am proposing below. Does this sound reasonable and
would this cause any problems for anyone?

Adrian.

[1] http://java.sun.com/j2se/1.4.2/docs/guide/nio

<snip/>


Jeremias Maerki



Reply via email to