Java JPEG首次压缩耗时远超后续运行的原因咨询
为什么Java图片压缩方法首次执行耗时远长于后续运行?
先来看你提供的压缩代码:
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()); }
这种首次执行慢、后续提速的现象在Java程序里很常见,主要是这几个原因导致的:
类加载与ImageIO初始化的一次性开销:第一次调用
ImageIO.getImageWritersByFormatName("jpg")时,JVM得加载一大堆和JPEG编码、图片IO相关的类,还要初始化ImageIO的插件注册表——它会扫描系统里可用的图像读写器实现,这个过程要花不少时间。等首次执行完,这些类已经在内存里了,注册表也初始化好了,后续调用就不用再做这些工作,自然更快。JIT编译的延迟优化:Java代码刚执行时是靠解释器跑的,速度比较慢。JVM的即时编译器(JIT)会盯着那些被频繁调用的代码,等判断出某段代码是热点后,就会把它编译成高效的本地机器码。你的压缩逻辑里核心的编码过程(比如
writer.write()里的操作)第一次跑是解释执行,后面几次跑的时候已经被JIT优化过了,所以速度会明显提升。文件系统与磁盘的预热开销:第一次创建
compressed_image.jpg并写入时,操作系统需要做文件分配、更新目录项、预热磁盘缓存这些操作。如果后续运行时这个文件还在,磁盘缓存里也已经有相关数据,那么文件读写的开销就会降低很多。底层资源的初始化成本:像
ImageOutputStream的创建、ImageWriteParam的配置,第一次执行时可能涉及一些底层资源的分配和初始化,后续调用时这些逻辑已经被JVM优化,甚至可能复用了内部缓存的对象,所以耗时减少。
内容的提问来源于stack exchange,提问作者Bartosz Sosnowski
相关产品推荐
相关产品推荐

