Base64编码图像的最快Java库是什么?

时间:2011-11-30 18:31:31

标签: java base64 encode

我目前正在使用ByteArrayOutputStream将BufferedImage转换为byte [],然后使用开源类Base64Coder将byte []转换为char [],然后附加到String。这是编码视频帧集并将其置于XML友好格式的多步骤过程的一部分。不要问为什么我这样做,这就是需要做的事情。

我看到Base64编码占用了整个过程大约75%的CPU时间,看到我刚从谷歌搜索中抓取这个随机类,我确信有更高效的编码图像。我有什么选择?

3 个答案:

答案 0 :(得分:3)

这是一个相当古老的问题,但它仍然出现在谷歌作为热门歌曲之一......

这里已经全面回答:http://java-performance.info/base64-encoding-and-decoding-performance/

从那里得到摘要:

让我们在一个表中总结编解码器属性。此表按所有这些编解码器的相对性能排序(顶部更快)。

Name        Max encoding    Max decoding    How much we can Supports    byte[] -> byte[]
            len             len             encode with -Xmx8G
Java 8      1.62 G          2 G             1.16 G                      Yes
javax.xml   1.62 G          2 G             1.07 G                      No
MiGBase64   1.62 G          0.36 G          1.07 G                      Yes
IHarder     1.62 G          0.72 G          1.23 G                      Yes
Apache      0.81 G          0.72 G          0.8 G                       Yes
Guava       1.62 G          2 G             1.07 G                      No
Sun.misc    0.79 G          1.05 G          0.78 G                      No

如果您正在寻找快速可靠的Base64编解码器 - 请不要在JDK之外查看。 Java 8中有一个新的编解码器:java.util.Base64并且还有许多眼睛(来自Java 6)隐藏了一个:javax.xml.bind.DatatypeConverter。两者都快速,可靠,不会出现整数溢出。

这里描述的4个第三方编解码器中有2个非常快:MiGBase64和IHarder。不幸的是,如果您需要一次处理数百兆字节,只有Google Guava允许您一次解码2G数据(如果是IHarder和Apache Commons,则为MiGBase64 / 720M时为360MB)。不幸的是,Guava不支持byte [] - > byte [] encoding。

如果您的字符集是多字节字符串,请不要尝试在巨大的字符串上调用String.getBytes(Charset) - 您可能会获得整数溢出相关异常的整个伽玛。

答案 1 :(得分:0)

http://commons.apache.org/codec/尝试commons-codec库 绝对让我们知道结果。这是一个标准且广泛使用的库。

您要找的班级是org.apache.commons.codec.binary.Base64 http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Base64.html

答案 2 :(得分:0)

@PaulWagland解决方案的问题在于,几乎所有编码器都会为您分配编码字节数组(或变量)。那是他们不是没有垃圾。

除非您知道自己在做什么,否则我不建议您这样做。

理想情况下,您要做的是将庞大的byte[]设置为您期望的最大大小,然后将其byte[]与threadlocal或某种类型的池一起重新使用。

不幸的是,Base64.java具有您要隐藏的方法:

private int decode0(byte[] src, int sp, int sl, byte[] dst) {
...
}

(我不会从JDK中粘贴代码,但我确定您可以轻松找到它)。

因此,如果您真的想快一点,可以在缓存的byte[]数组上使用该方法。

理想情况下,尽管您想重写它以使用ByteBuffers。

或者,您可以使用Base64.Decode#wrap作为停止间隔,但是该方法的问题是它将创建一个包装InputStream,这可能比分配新数组更好,但仍然没有垃圾。您还需要将ByteBuffer/byte[]数组包装在其自己的InputStream中。

IMO的缺点是Base64编码器/解码器没有CharsetEncoder具有的功能:

CharsetEncoder.encode(CharBuffer in, ByteBuffer out, boolean endOfInput)