gpt4 book ai didi

与其他语言相比,Java BufferedImage 到字节数组的转换太慢

转载 作者:行者123 更新时间:2023-11-30 02:21:32 30 4
gpt4 key购买 nike

我正在尝试将图像转换为字节数组,以便我可以通过网络传输它以进行进一步处理。

现在,在 C# 中,以下代码可在大约 3 或 2 毫秒内完成这项工作。

Image image = Image.FromFile("D:/tst.jpg");
DateTime pre = DateTime.Now;
int sz;
using (MemoryStream sourceImageStream = new MemoryStream())
{
image.Save(sourceImageStream, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] sourceImageData = sourceImageStream.ToArray();
sz = sourceImageData.Count();
}
MessageBox.Show("Size " + sz + " time : " + (DateTime.Now - pre).TotalMilliseconds);

输出:

Size 268152 time : 3.0118

但是在 Java 中执行与下面相同的操作会花费太多时间。

BuffredImage image = ImageIO.read(new File("D:/tst.jpg"));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Instant pre = Instant.now();
ImageIO.write( image, "jpeg", baos );
baos.flush();
Instant now = Instant.now();
System.out.println("Size " + baos.size() + " time : " + ChronoUnit.MILLIS.between(pre, now));

输出:

Size 268167 time : 91.0

源图像是 JPG 图像。在 C# 中使用 png 压缩时。时间约为90毫秒。所以我的猜测是 Java 需要时间以某种方式仍然压缩相同的 JPG 图像。图片尺寸为2048 * 1536。

Java 在这里慢得令人沮丧。我怎样才能摆脱Java中的这个问题?

拿这个image考虑在内。

C#:

Size 1987059 time : 11.0129

Java:

Size 845093 time : 155.0

源图像为 1987059 字节(与 C# 编码的字节数组相同)。但在Java中它被压缩为845093字节。我尝试将压缩质量设置为 1f 就像 this但这并没有帮助减少时间。

最佳答案

第一条评论指出了这种测试的主要问题:这是一个微基准。如果您在 Java 中只运行该代码一次,您将主要测量初始化运行时、类加载和初始化所花费的时间。

这是您的代码的稍微修改版本(我最初编写此代码是为了回答您的后续问题,该问题现已作为重复项关闭,但适用相同的概念),至少包括预热时间。您会发现测量结果存在很大差异。在我的 2014 MacBook Pro 上,输出是:

Initial load time 415 ms (5)
Average warm up load time 73 ms (5)
Normal load time 65 ms (5)

如您所见,加载图像的“正常”时间比初始时间少很多,其中包括大量开销。

代码:

public class TestJPEGSpeed {
public static void main(String[] args) throws IOException {
File input = new File(args[0]);

test(input, 1, "Initial");
test(input, 100, "Average warm up");
test(input, 1, "Normal");
}

private static void test(File input, int runs, final String type) throws IOException {
BufferedImage image = null;

long start = System.currentTimeMillis();
for (int i = 0; i < runs; i++) {
image = ImageIO.read(input);
}
long stop = System.currentTimeMillis();

System.out.println(type + " load time " + ((stop - start) / runs) + " ms (type=" + image.getType() + ")");
}
}

(我还编写了一个不同的版本,它采用了第二个参数,并在“正常”情况下加载了不同的文件,但测量结果相似,因此我将其省略)。

这个基准测试很可能仍然存在问题,例如测量 I/O 时间,而不是解码时间,但至少它更公平一点。

<小时/>

PS:一些额外的背景信息。如果您至少使用 Oracle JRE,ImageIO 的捆绑 JPEG 插件会使用 JNI 和 IJG 的 libjpeg 的 native 编译版本(用 C 编写)。这用于读取和写入 JPEG。如果您使用 libjpegTurbo 的 native 绑定(bind),您可能会看到更好的性能。但由于这都是 native 代码,因此不同平台的性能不太可能有很大差异。

关于与其他语言相比,Java BufferedImage 到字节数组的转换太慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46688650/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com