Skip to main content

[JAI] why is my performance using "Java only" faster than native?

7 replies [Last post]
Anonymous

Hi,
I have a servlet that reads a large TIFF image (200MB, ~7000x9000px)
and, based on an HTTP request returns a cropped and scaled JPEG
to the user (see code fragment below.) When I run this with the
native libraries, this operation takes, on the average, about 9
seconds. When I run it in "java only" mode (i removed the DLL-containing
directory from the Windows Path, causing JAI to print out that it's in
reverting to "Java Only" mode), the operations "only" take 5-6 seconds.

So the obvious questions are:
- why is the "native" operation time so much slower?
- is there any way I can get substantially better performance? I'm a newbie
to JAI - maybe I'm just doing things severly suboptimally? Take a look at
my code below.

My environment: Windows XP Professional with 1Gig RAM, dual 3Ghz
Pentium processors. Jvm parameters I gave are "-Xms128m -Xmx512m"

Many thanks for any help and/or pointers.
Tom

try {
HttpSession s = request.getSession(true);
RenderedOp workingImage = (RenderedOp) s.getAttribute("workingImage");
if (workingImage == null || !imageName.equals(workingName)) {
FileSeekableStream stream = new FileSeekableStream(imageName);
workingImage = JAI.create("stream", stream);
s.setAttribute("workingImage", workingImage);
}
...
// Do any cropping that needs to be done.
ParameterBlock pb = new ParameterBlock();
pb.addSource(workingImage);
pb.add((float) x);
pb.add((float) y);
pb.add((float) w);
pb.add((float) h);
workingImage = JAI.create("crop", pb);

// Zoom to the final image size
pb = new ParameterBlock();
pb.addSource(workingImage);
float iScale = (float) Viewer.IMAGE_WIDTH /
(float) workingImage.getWidth();
pb.add(iScale);
pb.add(iScale);
pb.add(0.0F); // The x translation
pb.add(0.0F); // The y translation
pb.add(new InterpolationNearest()); // The interpolation
workingImage = JAI.create("scale", pb);
JAI.create("encode", workingImage, out, "JPEG", null);
} catch (IOException e) {
e.printStackTrace();
}

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Kim van der Linde

Ok, I use a module to reduce batches of tiff images by 50 percent. The
original images are 298 KB, and approximatly 200 of them. On the old
imaging program, C++ (?) based, it took us over 30 minutes to do that.
With java only inplementation that I wrote, no acelerator, it takes less
than a minute. Ok, it is a reasonably fast computer.

Cheers,

Kim

Kevin Ryan wrote:

> You could try sending just TIFF images, or another format that doesn't
> take as long to prepare; avoid the issue by not doing the time consuming
> computation. Most browsers can read TIFF with a single plugin. The hit
> for not compressing will be about a factor of two in bandwidth/download
> time.
>
> -- KWR
>
>
>>-----Original Message-----
>>From: Thomas Wolf [mailto:twolf@ithaka.org]
>>Sent: Wednesday, June 29, 2005 3:29 PM
>>To: interest@jai.dev.java.net
>>Subject: Re: [JAI] why is my performance using "Java only"
>>faster than native?
>>
>>
>>James,
>>Thanks for your reply - here is some additional information:
>>
>>James Cheng wrote:
>>...
>>
>>>Another is the overhead of using the native library and the JNI
>>>interface, in some cases, extra data copying or
>>
>>reformatting has to be
>>
>>>done in order to use the native functions. It can be
>>
>>neglected only
>>
>>>when the operation is complicated. In your case, it seems
>>
>>to me that
>>
>>>only the "scale" operation uses native support. Since you
>>
>>are using
>>
>>>the NearestNeighbor interpolation, which doesn't do much
>>
>>computation,
>>
>>>using a native scale function might actually slow down the
>>
>>operation.
>>
>>I think this was it - my scaling operation, non-native, takes
>>less than a millisecond (scale factor 0.2), the crop
>>operation takes between 60 and 150ms.
>>
>>
>>>>- is there any way I can get substantially better performance?
>>>
>>>
>>>One thing you might like to try is the "SubsampleAverage"
>>
>>operator if
>>
>>>the scaling factor iScale is much smaller than 1.0. Another thing,
>>>you might try the TIFF and JPEG codecs from JAI Image I/O Tools.
>>
>>The bottleneck is definitely the JPEG (or PNG when I tried
>>it) encoding. It takes, on the average, over 5 seconds! I
>>tried using the JAI IMage I/O Tools as you suggested, but
>>they only improve things marginally - at least using the
>>method I tried:
>> javax.imageio.ImageIO.write(workingImage, "jpeg", out);
>>and
>> javax.imageio.ImageIO.write(workingImage, "png", out);
>>I didn't see any difference between the "native" encoding and
>>pure java.
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
> For additional commands, e-mail: interest-help@jai.dev.java.net
>

--
http://www.kimvdlinde.com

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net

James Cheng

Tom,

> I think this was it - my scaling operation, non-native, takes less than a
> millisecond (scale factor 0.2), the crop operation takes between 60 and 150ms.

I am surprised that the scaling operation could be that fast. It
might have been deferred. In other words, part of the JPEG encoding
time you observed might be actually for scaling.

> The bottleneck is definitely the JPEG (or PNG when I tried it) encoding.
> It takes, on the average, over 5 seconds!
> I tried using the JAI IMage I/O Tools as you suggested, but they only
> improve things marginally - at least using the method I tried:
> javax.imageio.ImageIO.write(workingImage, "jpeg", out);
> and
> javax.imageio.ImageIO.write(workingImage, "png", out);
> I didn't see any difference between the "native" encoding and pure java.

There is also the built-in subsampling in the Java Image I/O codecs.
I am not sure if the JPEG encoder in JAI Image I/O Tools supports that.
But if yes, it could be faster than using JAI's scale operator, with
only a drawback of requiring the subsampling ratios to be integers.

Regards,
-James

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net

Brian Burkhalter

The subsampling in the JPEG writers in core J2SE and in JAI-Image I/O Tools is
equivalent to nearest neighbor subsampling by integral factors. The core J2SE
JPEG writer is likely to be more efficient in this regard as the one in
JAI-Image I/O Tools (as stated in the javadoc) will do the subsampling in
memory before passing the result to the native JPEG encoder.

Brian

> There is also the built-in subsampling in the Java Image I/O codecs.
> I am not sure if the JPEG encoder in JAI Image I/O Tools supports that.
> But if yes, it could be faster than using JAI's scale operator, with
> only a drawback of requiring the subsampling ratios to be integers.

----------------
Brian Burkhalter
Advanced Development/Media & Entertainment
Market Development Engineering
Sun Microsystems, Inc.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This email message is for the sole use of the intended recipient(s)
and may contain confidential and privileged information. Any
unauthorized review, use, disclosure or distribution is prohibited.
If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net

James Cheng

Hi Tom,

> - why is the "native" operation time so much slower?

There are at least two things which can be attributed to the slowness
when a native library is used. One is the extra native library loading
time, which can be couple of hundred milliseconds. It's a one-time
overhead for each instance of JVM.

Another is the overhead of using the native library and the JNI
interface, in some cases, extra data copying or reformatting has to be
done in order to use the native functions. It can be neglected only
when the operation is complicated. In your case, it seems to me that
only the "scale" operation uses native support. Since you are using
the NearestNeighbor interpolation, which doesn't do much computation,
using a native scale function might actually slow down the operation.

> - is there any way I can get substantially better performance?

One thing you might like to try is the "SubsampleAverage" operator
if the scaling factor iScale is much smaller than 1.0. Another thing,
you might try the TIFF and JPEG codecs from JAI Image I/O Tools.

HTH,
-James

On 06/27/05 01:41 PM, Thomas Wolf wrote:
> Hi,
> I have a servlet that reads a large TIFF image (200MB, ~7000x9000px)
> and, based on an HTTP request returns a cropped and scaled JPEG
> to the user (see code fragment below.) When I run this with the
> native libraries, this operation takes, on the average, about 9
> seconds. When I run it in "java only" mode (i removed the DLL-containing
> directory from the Windows Path, causing JAI to print out that it's in
> reverting to "Java Only" mode), the operations "only" take 5-6 seconds.
>
> So the obvious questions are:
> - why is the "native" operation time so much slower?
> - is there any way I can get substantially better performance? I'm a newbie
> to JAI - maybe I'm just doing things severly suboptimally? Take a look at
> my code below.
>
> My environment: Windows XP Professional with 1Gig RAM, dual 3Ghz
> Pentium processors. Jvm parameters I gave are "-Xms128m -Xmx512m"
>
> Many thanks for any help and/or pointers.
> Tom
>
>
> try {
> HttpSession s = request.getSession(true);
> RenderedOp workingImage = (RenderedOp) s.getAttribute("workingImage");
> if (workingImage == null || !imageName.equals(workingName)) {
> FileSeekableStream stream = new FileSeekableStream(imageName);
> workingImage = JAI.create("stream", stream);
> s.setAttribute("workingImage", workingImage);
> }
> ...
> // Do any cropping that needs to be done.
> ParameterBlock pb = new ParameterBlock();
> pb.addSource(workingImage);
> pb.add((float) x);
> pb.add((float) y);
> pb.add((float) w);
> pb.add((float) h);
> workingImage = JAI.create("crop", pb);
>
> // Zoom to the final image size
> pb = new ParameterBlock();
> pb.addSource(workingImage);
> float iScale = (float) Viewer.IMAGE_WIDTH /
> (float) workingImage.getWidth();
> pb.add(iScale);
> pb.add(iScale);
> pb.add(0.0F); // The x translation
> pb.add(0.0F); // The y translation
> pb.add(new InterpolationNearest()); // The interpolation
> workingImage = JAI.create("scale", pb);
> JAI.create("encode", workingImage, out, "JPEG", null);
> } catch (IOException e) {
> e.printStackTrace();
> }
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
> For additional commands, e-mail: interest-help@jai.dev.java.net
>

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net

Thomas Wolf

James,
Thanks for your reply - here is some additional information:

James Cheng wrote:
...
> Another is the overhead of using the native library and the JNI
> interface, in some cases, extra data copying or reformatting has to be
> done in order to use the native functions. It can be neglected only
> when the operation is complicated. In your case, it seems to me that
> only the "scale" operation uses native support. Since you are using
> the NearestNeighbor interpolation, which doesn't do much computation,
> using a native scale function might actually slow down the operation.

I think this was it - my scaling operation, non-native, takes less than a
millisecond (scale factor 0.2), the crop operation takes between 60 and 150ms.

>>- is there any way I can get substantially better performance?
>
>
> One thing you might like to try is the "SubsampleAverage" operator
> if the scaling factor iScale is much smaller than 1.0. Another thing,
> you might try the TIFF and JPEG codecs from JAI Image I/O Tools.

The bottleneck is definitely the JPEG (or PNG when I tried it) encoding.
It takes, on the average, over 5 seconds!
I tried using the JAI IMage I/O Tools as you suggested, but they only
improve things marginally - at least using the method I tried:
javax.imageio.ImageIO.write(workingImage, "jpeg", out);
and
javax.imageio.ImageIO.write(workingImage, "png", out);
I didn't see any difference between the "native" encoding and pure java.

I suppose there's no hope of getting this number to within 1-2 seconds?
I'm doing this to allow users on older browsers and with limited CPU
& memory to do zooming/panning of these huge TIFF images (200mb.)

Any further suggestions are much appreciated.
tom

>
> HTH,
> -James
>
> On 06/27/05 01:41 PM, Thomas Wolf wrote:
>
>>Hi,
>>I have a servlet that reads a large TIFF image (200MB, ~7000x9000px)
>>and, based on an HTTP request returns a cropped and scaled JPEG
>>to the user (see code fragment below.) When I run this with the
>>native libraries, this operation takes, on the average, about 9
>>seconds. When I run it in "java only" mode (i removed the DLL-containing
>>directory from the Windows Path, causing JAI to print out that it's in
>>reverting to "Java Only" mode), the operations "only" take 5-6 seconds.
>>
>>So the obvious questions are:
>>- why is the "native" operation time so much slower?
>>- is there any way I can get substantially better performance? I'm a newbie
>>to JAI - maybe I'm just doing things severly suboptimally? Take a look at
>>my code below.
>>
>>My environment: Windows XP Professional with 1Gig RAM, dual 3Ghz
>>Pentium processors. Jvm parameters I gave are "-Xms128m -Xmx512m"
>>
>>Many thanks for any help and/or pointers.
>>Tom
>>
>>
>>try {
>> HttpSession s = request.getSession(true);
>> RenderedOp workingImage = (RenderedOp) s.getAttribute("workingImage");
>> if (workingImage == null || !imageName.equals(workingName)) {
>> FileSeekableStream stream = new FileSeekableStream(imageName);
>> workingImage = JAI.create("stream", stream);
>> s.setAttribute("workingImage", workingImage);
>> }
>> ...
>> // Do any cropping that needs to be done.
>> ParameterBlock pb = new ParameterBlock();
>> pb.addSource(workingImage);
>> pb.add((float) x);
>> pb.add((float) y);
>> pb.add((float) w);
>> pb.add((float) h);
>> workingImage = JAI.create("crop", pb);
>>
>> // Zoom to the final image size
>> pb = new ParameterBlock();
>> pb.addSource(workingImage);
>> float iScale = (float) Viewer.IMAGE_WIDTH /
>> (float) workingImage.getWidth();
>> pb.add(iScale);
>> pb.add(iScale);
>> pb.add(0.0F); // The x translation
>> pb.add(0.0F); // The y translation
>> pb.add(new InterpolationNearest()); // The interpolation
>> workingImage = JAI.create("scale", pb);
>> JAI.create("encode", workingImage, out, "JPEG", null);
>>} catch (IOException e) {
>> e.printStackTrace();
>>}
>>
>>
>>---------------------------------------------------------------------
>>To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
>>For additional commands, e-mail: interest-help@jai.dev.java.net
>>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
> For additional commands, e-mail: interest-help@jai.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net

Kevin Ryan

You could try sending just TIFF images, or another format that doesn't
take as long to prepare; avoid the issue by not doing the time consuming
computation. Most browsers can read TIFF with a single plugin. The hit
for not compressing will be about a factor of two in bandwidth/download
time.

-- KWR

> -----Original Message-----
> From: Thomas Wolf [mailto:twolf@ithaka.org]
> Sent: Wednesday, June 29, 2005 3:29 PM
> To: interest@jai.dev.java.net
> Subject: Re: [JAI] why is my performance using "Java only"
> faster than native?
>
>
> James,
> Thanks for your reply - here is some additional information:
>
> James Cheng wrote:
> ...
> > Another is the overhead of using the native library and the JNI
> > interface, in some cases, extra data copying or
> reformatting has to be
> > done in order to use the native functions. It can be
> neglected only
> > when the operation is complicated. In your case, it seems
> to me that
> > only the "scale" operation uses native support. Since you
> are using
> > the NearestNeighbor interpolation, which doesn't do much
> computation,
> > using a native scale function might actually slow down the
> operation.
>
> I think this was it - my scaling operation, non-native, takes
> less than a millisecond (scale factor 0.2), the crop
> operation takes between 60 and 150ms.
>
> >>- is there any way I can get substantially better performance?
> >
> >
> > One thing you might like to try is the "SubsampleAverage"
> operator if
> > the scaling factor iScale is much smaller than 1.0. Another thing,
> > you might try the TIFF and JPEG codecs from JAI Image I/O Tools.
>
> The bottleneck is definitely the JPEG (or PNG when I tried
> it) encoding. It takes, on the average, over 5 seconds! I
> tried using the JAI IMage I/O Tools as you suggested, but
> they only improve things marginally - at least using the
> method I tried:
> javax.imageio.ImageIO.write(workingImage, "jpeg", out);
> and
> javax.imageio.ImageIO.write(workingImage, "png", out);
> I didn't see any difference between the "native" encoding and
> pure java.

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net

Thomas Wolf

That's a good idea - but I don't know which format (supported by all browsers)
takes the least amount of processing. I thought 'png' might be one - but it
took quite long. I will try TIFF and GIF next.

thx,
tom

Kevin Ryan wrote:
> You could try sending just TIFF images, or another format that doesn't
> take as long to prepare; avoid the issue by not doing the time consuming
> computation. Most browsers can read TIFF with a single plugin. The hit
> for not compressing will be about a factor of two in bandwidth/download
> time.
>
> -- KWR
>
>
>>-----Original Message-----
>>From: Thomas Wolf [mailto:twolf@ithaka.org]
>>Sent: Wednesday, June 29, 2005 3:29 PM
>>To: interest@jai.dev.java.net
>>Subject: Re: [JAI] why is my performance using "Java only"
>>faster than native?
>>
>>
>>James,
>>Thanks for your reply - here is some additional information:
>>
>>James Cheng wrote:
>>...
>>
>>>Another is the overhead of using the native library and the JNI
>>>interface, in some cases, extra data copying or
>>
>>reformatting has to be
>>
>>>done in order to use the native functions. It can be
>>
>>neglected only
>>
>>>when the operation is complicated. In your case, it seems
>>
>>to me that
>>
>>>only the "scale" operation uses native support. Since you
>>
>>are using
>>
>>>the NearestNeighbor interpolation, which doesn't do much
>>
>>computation,
>>
>>>using a native scale function might actually slow down the
>>
>>operation.
>>
>>I think this was it - my scaling operation, non-native, takes
>>less than a millisecond (scale factor 0.2), the crop
>>operation takes between 60 and 150ms.
>>
>>
>>>>- is there any way I can get substantially better performance?
>>>
>>>
>>>One thing you might like to try is the "SubsampleAverage"
>>
>>operator if
>>
>>>the scaling factor iScale is much smaller than 1.0. Another thing,
>>>you might try the TIFF and JPEG codecs from JAI Image I/O Tools.
>>
>>The bottleneck is definitely the JPEG (or PNG when I tried
>>it) encoding. It takes, on the average, over 5 seconds! I
>>tried using the JAI IMage I/O Tools as you suggested, but
>>they only improve things marginally - at least using the
>>method I tried:
>> javax.imageio.ImageIO.write(workingImage, "jpeg", out);
>>and
>> javax.imageio.ImageIO.write(workingImage, "png", out);
>>I didn't see any difference between the "native" encoding and
>>pure java.
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
> For additional commands, e-mail: interest-help@jai.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net