Torturing image ops and Swing

Sven de Marothy sven at physto.se
Thu Aug 3 21:54:59 UTC 2006


On Thu, 2006-08-03 at 22:28 +0200, hendrich at informatik.uni-hamburg.de
wrote:
> Hello Sven,
> 
> thanks for your detailed answers to my questions!  New Niffler version  
> uploaded
> and available right now (niffler-exif.jar and niffler-src.zip).

Ok good. :)

> I added a special "classpath workaround" to Niffler that checks for  
> "java.vendor"
> and calls ImageUtils.getCairoBackedImage( bufferedImage) before rendering when
> "GNU something" is detected. This adds another image conversion (BufferedImage
> drawn into an Image created by Component.createImage()), but makes the editing
> operations useable with jamvm. Good.

Well, lemme just point out that Component.createImage() is basically the
same thing as calling GraphicsConfiguration.createCompatibleImage() for
the GraphicsConfiguration of that Component (Read: The
graphicsconfiguration of your screen). 

So as such, it's supposed to return a BufferedImage with a pixel format
best suited for fast drawing on your screen (using whatever color mode
you've got set). So this will always result in faster images, regardless
of Java impl.

> Yep. Please excuse my typo there; the 7 and 200+ seconds are for jamvm and
> classpath loading a 800x600 or 3000x2000 JPEG via the imageio JPEG plugin.
> You can try the 10+ MPixel images from the Brussels' mort subite for  
> yourself...

Yes, the existing ImageIO plugin for JPEG (Which is a generic wrapper
around gdk-pixbuf that someone coded) is totaly flawed. I haven't
actually looked at the code, but I think that however it's doing its job
it's doing it in a horribly bad way. The plan (or my plan at least) is
to just throw this out as soon as we get a real JPEG decoder.

> > Really? That sounds too fast, almost. How do you mean conversion?
> > Running it through a filter, or just drawing the image returned by
> > IIO onto the the aforementioned BufferedImagE?
> 
> You consider, 4+90 seconds too fast for 3000x2000?  Wait for next years'
> digicams and cellphone cams :-)

90 seconds is very slow. But that part wasn't so unexpected to me, it's
basically due to the inefficient awt.image impl we have. But 5 seconds
to decode such a large GIF is pretty dang good considering that it's
all done in Java. (I guess I'm particularily interested in this since
I wrote the GIF decoder).

[ JTextArea in a JScrollPanel with 700 lines .. ]

> > I'll have to check this out. drawString is fairly slow nowadays.
> > However, drawGlyphVector (and by extension TextLayout.draw) are quite
> > snappy, comparable to the JDK in speed. We might need to tune
> > Swing here.
> 
> Should I submit another bug for this?  Once upon a time, this used to be
> PR24152...

Naw, I'll do it. I'll want to check up on where the problem is first. 
While drawString() is slow, I doubt a that bit it's slow enough to
render the thing unusable. It's probably something else.
(Basically we're talking about rendering a large string in 4 ms or .4
ms, but since I assume you're not showing all 700 at once, I doubt
that's it.)

> I guess we need some technique to include performance-related tests in
> Mauve for regular regression testing. Unfortunately, I don't know how to
> do this, because both raw system speed and "user picky-ness" seem to
> differ greatly between different systems...

I'd much rather not. Tests in general and benchmarks in particular often
make people lose focus. IMHO, people will tend to fix the test but
sometimes cause a worse regression in something not as well tested.

With a fixed set of benchmarks people will invariably end up sacrificing
speed of non-benchmarked things to improve the benchmark scores. Either
that, or there's a large risk they'll start microoptimizing and trying
to improve things that are already more than adequately fast while
ignoring bigger problems elsewhere. 
"Premature optimization is the root of all evil". 

So my opinion is that we should do benchmarking, but the way we 
tend to do it now; sporadically and thoroughly by the people 
hacking on the code and know it well, and know what to look 
for and what to check for. 

Writing a benchmark is trivial. Writing a benchmark that actually
measures something meaningful is not.

In short: Superficial automated benchmarks will only result in
superficial automated optimizations. 

To give a practical example, there about a half dozen optimizations
I know about which could improve the drawing performance of
CairoGraphics2D for shapes. (not images) I posted the results earlier,
which were that they're entirely insignificant because Cairo is so very
slow. And in that case, it's not worth complicating the code at this
stage for what amounts to almost nothing relatively speaking.

Plus some speed losses are simply necessary. You can't expect to improve
performance consistently in code as immature as most of our Java2D code.
There are some fundamental design issues that need to be fixed first.

/Sven




More information about the Classpath mailing list