Java JPEG压缩时间

Java JPEG compression time

我有一种方法可以将图像压缩为 jpg 格式和 returns 它的一个字节数组。这是它的代码:

public static byte[] CompressToJpeg(BufferedImage image, float compressionQuality) throws IOException {
    File compressedImageFile = new File("compressed_image.jpg");
    OutputStream os = new FileOutputStream(compressedImageFile);

    Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");
    ImageWriter writer = (ImageWriter) writers.next();

    ImageOutputStream ios = ImageIO.createImageOutputStream(os);
    writer.setOutput(ios);

    ImageWriteParam param = writer.getDefaultWriteParam();

    param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    param.setCompressionQuality(compressionQuality);
    writer.write(null, new IIOImage(image, null, null), param);

    os.close();
    ios.close();
    writer.dispose();

    return Files.readAllBytes(compressedImageFile.toPath());
}

并且总是当我 运行 第一次进行这种压缩时,它比接下来的 运行 花费的时间要长得多。我的问题是为什么会这样?

正如我在评论中发布的 link 中提到的,这对所有事物都是通用的 Java:

任何东西的第一次执行 Java 总是比随后的 运行 慢。有启动开销,因为...

一般:

  • 第一次使用 class 时,class 加载程序必须查找、加载、验证和初始化 class。
  • 第一次的代码是运行,被解释了。 Hotspot/the JIT 稍后会在某个预定义的阈值之后对其进行优化。如果您的代码第一次达到此阈值(即循环),它的某些部分可能会在第一个 运行 上进行优化,花费更多时间。

ImageIO class 特别是在启动时要做很多事情:

  • 所有可用插件的服务提供商查找和实例化。可用的插件越多,花费的时间就越多。
  • 因为它是 Java 桌面模块的一部分,它的某些部分或插件可能会触发 Java2D 子系统的初始化。使用无头系统 属性 可能有助于加快速度。
  • 尤其是JPEG插件,使用原生代码,第一次执行时也需要加载、初始化。

(另外,可能还有更多我没有想到的东西)。