-
Enhancement
-
Resolution: Cannot Reproduce
-
P3
-
None
-
5.0
-
x86
-
linux
A DESCRIPTION OF THE REQUEST :
Image loading using Toolkit.getImage is 30-80% slower in Linux Java (1.5.0_05) than in Windows Java for large images, even if windows java is running in wine (windows emulator) in Linux (!!!). Both JPEG and PNG loading are slower.
JUSTIFICATION :
Waiting is always painful, especially in case of a slideshow program. Although JPEG reading is much faster in java 1.5 than in 1.4, it is still slow compared to windows java.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
There should be no speed difference. Linux java should use the same, faster JPEG and PNG readers as windows java.
ACTUAL -
Test results:
- GetImageTest with empty 15000x1000 JPEGs generated using imageio:
12.19s P4 2.4GHz, SuSE Linux 10 RC1, Java 1.5.0_05-linux
6.85s P4 2.4GHz, wine20050725/SuSE Linux 10 RC1, Java 1.5.0_05-win
(first column is the runtime in seconds)
- GetImageTest with empty 15000x1000 PNGs generated using imageio:
9.514s P4 2.4GHz, SuSE Linux 10 RC1, Java 1.5.0_05-linux
7.266s P4 2.4GHz, wine20050725/SuSE Linux 10 RC1, Java 1.5.0_05-win
- loading some digital photos (large panorama images, JPEG) with SlideProject, a java slideshow program:
31.2s P4 3.0GHz, SuSE Linux 9.1, Java 1.5.0_05-linux
19.9s P4 3.0GHz, Windows XP, Java 1.5.0_05-win
40.2s P4 2.4GHz, SuSE Linux 10 RC1, Java 1.5.0_05-linux
29.8s P4 2.4GHz, wine20050725/SuSE Linux 10 RC1, Java 1.5.0_05-win
---------- BEGIN SOURCE ----------
CreateImages.java - program for creating the large test JPEGs:
import java.awt.image.BufferedImage;
import java.util.Iterator;
import java.io.*;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import javax.imageio.*;
import javax.imageio.stream.ImageOutputStream;
public class CreateImages {
public static void main(String[] args) throws Exception {
// create jpg files by default or png if it is specified in first arg
String fmt = args.length != 0? args[0] : "jpg";
// create empty 15000x1000 image file b0.jpg or b0.png
int[] pixels = new int[15000];
BufferedImage im = new BufferedImage(15000, 1000,
BufferedImage.TYPE_INT_RGB);
Iterator it = ImageIO.getImageWritersByFormatName(fmt);
ImageWriter wr = (ImageWriter)it.next();
ImageOutputStream ios = ImageIO.createImageOutputStream(
new File("b0."+fmt));
wr.setOutput(ios);
wr.write(null, new IIOImage(im, null, null), null);
ios.flush();
wr.dispose();
ios.close();
// create b1.jpg, ..., b9.jpg files by copying b0.jpg
for(int i = 1; i < 10; ++i) {
FileChannel in = new FileInputStream("b0."+fmt).getChannel();
FileChannel out = new FileOutputStream("b"+i+"."+fmt).getChannel();
long size = in.size();
MappedByteBuffer buf = in.map(FileChannel.MapMode.READ_ONLY, 0, size);
out.write(buf);
in.close();
out.close();
}
}
}
GetImageTest.java - the test program:
import java.awt.*;
import java.io.File;
import javax.swing.*;
public class GetImageTest extends JFrame {
static final String[] DEFAULT_FILENAMES = new String[] {
"b0.jpg", "b1.jpg", "b2.jpg", "b3.jpg", "b4.jpg",
"b5.jpg", "b6.jpg", "b7.jpg", "b8.jpg", "b9.jpg"};
JTextArea txt;
GetImageTest(int nrows) {
super("GetImageTest");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new GridLayout());
getContentPane().add(txt = new JTextArea(nrows, 80));
txt.setFont(new Font("Monospaced", Font.PLAIN, 12));
pack();
}
int getImage(String fname) throws InterruptedException {
Thread.sleep(500); // 0.5s rest before start
long t0 = System.currentTimeMillis();
Image im = getToolkit().getImage(fname); // load image
MediaTracker mt = new MediaTracker(this);
mt.addImage(im, 0);
mt.waitForAll();
int t = (int)(System.currentTimeMillis() - t0); // milliseconds elapsed
txt.append(String.format("%.3f %3.1fM %4.1fMpix %5dx%-4d %s\n",
0.001*t, (new File(fname).length())/1048576.0,
1e-6*im.getWidth(null)*im.getHeight(null),
im.getWidth(null), im.getHeight(null), fname));
return t;
}
public static void main(String[] args) throws Exception {
String[] fnames = args.length != 0? args : DEFAULT_FILENAMES;
GetImageTest w = new GetImageTest(fnames.length + 2);
w.setVisible(true);
int tot = 0; // total time elapsed in milliseconds
for(int i = 0; i < fnames.length; ++i) {
int t = w.getImage(fnames[i]);
tot += t;
}
// print total time elapsed in seconds
w.txt.append(String.format("%.3f", 0.001*tot));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Buying an 80% faster computer or trying to use the windows JVM with wine instead of the native linux JVM.
Image loading using Toolkit.getImage is 30-80% slower in Linux Java (1.5.0_05) than in Windows Java for large images, even if windows java is running in wine (windows emulator) in Linux (!!!). Both JPEG and PNG loading are slower.
JUSTIFICATION :
Waiting is always painful, especially in case of a slideshow program. Although JPEG reading is much faster in java 1.5 than in 1.4, it is still slow compared to windows java.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
There should be no speed difference. Linux java should use the same, faster JPEG and PNG readers as windows java.
ACTUAL -
Test results:
- GetImageTest with empty 15000x1000 JPEGs generated using imageio:
12.19s P4 2.4GHz, SuSE Linux 10 RC1, Java 1.5.0_05-linux
6.85s P4 2.4GHz, wine20050725/SuSE Linux 10 RC1, Java 1.5.0_05-win
(first column is the runtime in seconds)
- GetImageTest with empty 15000x1000 PNGs generated using imageio:
9.514s P4 2.4GHz, SuSE Linux 10 RC1, Java 1.5.0_05-linux
7.266s P4 2.4GHz, wine20050725/SuSE Linux 10 RC1, Java 1.5.0_05-win
- loading some digital photos (large panorama images, JPEG) with SlideProject, a java slideshow program:
31.2s P4 3.0GHz, SuSE Linux 9.1, Java 1.5.0_05-linux
19.9s P4 3.0GHz, Windows XP, Java 1.5.0_05-win
40.2s P4 2.4GHz, SuSE Linux 10 RC1, Java 1.5.0_05-linux
29.8s P4 2.4GHz, wine20050725/SuSE Linux 10 RC1, Java 1.5.0_05-win
---------- BEGIN SOURCE ----------
CreateImages.java - program for creating the large test JPEGs:
import java.awt.image.BufferedImage;
import java.util.Iterator;
import java.io.*;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import javax.imageio.*;
import javax.imageio.stream.ImageOutputStream;
public class CreateImages {
public static void main(String[] args) throws Exception {
// create jpg files by default or png if it is specified in first arg
String fmt = args.length != 0? args[0] : "jpg";
// create empty 15000x1000 image file b0.jpg or b0.png
int[] pixels = new int[15000];
BufferedImage im = new BufferedImage(15000, 1000,
BufferedImage.TYPE_INT_RGB);
Iterator it = ImageIO.getImageWritersByFormatName(fmt);
ImageWriter wr = (ImageWriter)it.next();
ImageOutputStream ios = ImageIO.createImageOutputStream(
new File("b0."+fmt));
wr.setOutput(ios);
wr.write(null, new IIOImage(im, null, null), null);
ios.flush();
wr.dispose();
ios.close();
// create b1.jpg, ..., b9.jpg files by copying b0.jpg
for(int i = 1; i < 10; ++i) {
FileChannel in = new FileInputStream("b0."+fmt).getChannel();
FileChannel out = new FileOutputStream("b"+i+"."+fmt).getChannel();
long size = in.size();
MappedByteBuffer buf = in.map(FileChannel.MapMode.READ_ONLY, 0, size);
out.write(buf);
in.close();
out.close();
}
}
}
GetImageTest.java - the test program:
import java.awt.*;
import java.io.File;
import javax.swing.*;
public class GetImageTest extends JFrame {
static final String[] DEFAULT_FILENAMES = new String[] {
"b0.jpg", "b1.jpg", "b2.jpg", "b3.jpg", "b4.jpg",
"b5.jpg", "b6.jpg", "b7.jpg", "b8.jpg", "b9.jpg"};
JTextArea txt;
GetImageTest(int nrows) {
super("GetImageTest");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new GridLayout());
getContentPane().add(txt = new JTextArea(nrows, 80));
txt.setFont(new Font("Monospaced", Font.PLAIN, 12));
pack();
}
int getImage(String fname) throws InterruptedException {
Thread.sleep(500); // 0.5s rest before start
long t0 = System.currentTimeMillis();
Image im = getToolkit().getImage(fname); // load image
MediaTracker mt = new MediaTracker(this);
mt.addImage(im, 0);
mt.waitForAll();
int t = (int)(System.currentTimeMillis() - t0); // milliseconds elapsed
txt.append(String.format("%.3f %3.1fM %4.1fMpix %5dx%-4d %s\n",
0.001*t, (new File(fname).length())/1048576.0,
1e-6*im.getWidth(null)*im.getHeight(null),
im.getWidth(null), im.getHeight(null), fname));
return t;
}
public static void main(String[] args) throws Exception {
String[] fnames = args.length != 0? args : DEFAULT_FILENAMES;
GetImageTest w = new GetImageTest(fnames.length + 2);
w.setVisible(true);
int tot = 0; // total time elapsed in milliseconds
for(int i = 0; i < fnames.length; ++i) {
int t = w.getImage(fnames[i]);
tot += t;
}
// print total time elapsed in seconds
w.txt.append(String.format("%.3f", 0.001*tot));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Buying an 80% faster computer or trying to use the windows JVM with wine instead of the native linux JVM.
- relates to
-
JDK-5105922 Linux build does not optimize AWT and other essential libraries
-
- Resolved
-