我目前正在使用ByteArrayOutputStream将BufferedImage转换为byte [],然后使用开源类Base64Coder将byte []转换为char [],然后附加到String。这是编码视频帧集并将其置于XML友好格式的多步骤过程的一部分。不要问为什么我这样做,这就是需要做的事情。
我看到Base64编码占用了整个过程大约75%的CPU时间,看到我刚从谷歌搜索中抓取这个随机类,我确信有更高效的编码图像。我有什么选择?
答案 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)