I have devised an applet which can be used to compare the performance of the Java2D Graphics2D object with respect to other software rendering algorithms implemented in pure Java.
For the comparison, the Java2D Graphics2D object renders on a BufferedImage. All rendering hints are set to speed up the rendering performance.
The drawing algorithms used for comparison are a
Bresenham line drawing algorithm and a Scan Fill algorithm taken from the
following
book:
Hearn, D., Baker, M. (1994). Computer Graphics. Second Edition. New Jersey:
Prentice Hall.
I have implemented a single-threaded version and a concurrent version of these algorithms. The concurrent version does not come from the book. I made it by myself. - I disabled the concurrent version temporarily -.
The algorithms render on a BufferedImage with a packed, integer RGB sample model. The "accelerationPriority" of the BufferedImage is set to 0 when running on a Java 1.5 VM.
Before you read the results, you may want to try
the applet by yourself. Either run some benchmarks or play around with some
individual tests.
Here are some of the measured results on a Mac Mini with a 1.42 Ghz PPC G4 processor using Java 1.5.0_06.
Java2D | Single-Threaded | Concurrent | |
drawLine 1,000 times | 17 | 43 | - |
drawLine 1,000 times with alpha | 16 | 35 | - |
drawLine 1,000 times antialiased | 12 | 24 | - |
drawLine 1,000 times same color | 21 | 46 | - |
drawLine 1,000 vert./horiz. | 25 | 50 | - |
drawLine 3,000 short lines | 18 | 41 | - |
drawLine 3,000 short same color | 38 | 46 | - |
drawRect 500 times | 20 | 43 | - |
drawGeneralPath 400 times | 6 | 12 | - |
fillRect 500 times | 15 | 14 | - |
fillRect 250 times with alpha | 8 | 4 | - |
fillRect 1,000 vert./horiz. | 44 | 51 | - |
fillPolygon 500 times | 6 | 6 | |
fill GeneralPath 400 times | 4 | 6 | - |
fill GeneralPath 200 with alpha | 5 | 3 | - |
Here the measured results on the same computer using Java 1.4.2_09.
Java2D | Single-Threaded | Concurrent | |
drawLine 1,000 times | 17 | 60 | - |
drawLine 1'000 times with alpha | 17 | 47 | - |
drawLine 1,000 times antialiased | 12 | 29 | |
drawLine 1,000 times same color | 20 | 59 | - |
drawLine 1,000 vert./horiz. | 26 | 62 | - |
drawLine 3,000 short lines | 20 | 58 | - |
drawLine 3,000 short same color | 40 | 58 | - |
drawRect 500 times | 21 | 56 | - |
drawGeneralPath 400 times | 6 | 15 | - |
fillRect 500 times | 15 | 15 | - |
fillRect 250 times with alpha | 8 | 8 | - |
fillRect 1,000 vert./horiz. | 43 | 64 | - |
fillPolygon 500 times | 6 | 7 | |
fill GeneralPath 400 times | 4 | 6 | - |
fill GeneralPath 200 with alpha | 5 | 5 | - |
Here the measured results on the same computer using Java 1.3.1_16.
Java2D | Single-Threaded | Concurrent | |
drawLine 1,000 times | 13 | 58 | - |
drawLine 1'000 times with alpha | 12 | 46 | - |
drawLine 1,000 times antialiased | 8 | 29 | |
drawLine 1,000 times same color | 17 | 58 | - |
drawLine 1,000 vert./horiz. | 25 | 63 | - |
drawLine 3,000 short lines | 11 | 61 | - |
drawLine 3,000 short same color | 20 | 68 | - |
drawRect 500 times | 26 | 48 | - |
drawGeneralPath 400 times | 6 | 13 | - |
fillRect 500 times | 12 | 15 | - |
fillRect 250 times with alpha | 8 | 6 | - |
fillRect 1,000 vert./horiz. | 29 | 67 | - |
fillPolygon 500 times | 6 | 5 | |
fill GeneralPath 400 times | 4 | 4 | - |
fill GeneralPath 200 with alpha | 5 | 4 | - |
I expected to see Java2D perform much better than my algorithms - after all, Java2D is implemented using native code.
Interestingly, most single-threaded algorithms perform decently with respect to Java2D. In some cases they are much faster than Java2D. This means, that either there is still some potential for performance improvement in the Java2D rendering pipeline, or the JVM is so good, that drawing algorithms implemented in pure Java can compete with native code.
Also it is interesting to see that the single threaded comparison code performs much better with Java 1.3 and 1.4 than with Java 1.5.
The concurrent algorithms perform worse on the Mac Mini than the other algorithms. This is what I expected, but I didn't expect them to be so much slower - so I conclude, I didn't implement the concurrent code very well. The concurrent algorithms are designed for multi-processor computers anyway. Unfortunately I haven't got such a computer at hand to see whether they can improve their performance relative to the other algorithms.