【问题标题】:What is the fastest Java library for Base64 encoding images?用于 Base64 编码图像的最快 Java 库是什么?
【发布时间】:2011-11-30 18:31:30
【问题描述】:

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

我看到 Base64 编码在整个过程中占用了大约 75% 的 CPU 时间,并且看到我刚刚从谷歌搜索中抓取了这个随机类,我确信那里有更有效的方法来编码图像.伙计们,我有什么选择?

【问题讨论】:

  • 比什么更有效率?给出算法,否则我们无法告诉你可以改进的地方。
  • 我已经告诉过你这个类,Base64Coder,它是谷歌搜索的第一个结果......
  • 我发现我测试过的所有课程在速度方面都相当。在慢速 VM 上运行,Apache commons Base64 类、Base64Coder 类和 MiGBase64 类都将 300 ~15kb 捕获的 jpeg 帧转换为 Base64 字符串,并在 69 秒内将它们输出为 XML。猜猜这是最好的。谢谢大家!

标签: java base64 encode


【解决方案1】:

这是一个相当古老的问题,但它仍然在 Google 中成为热门话题之一……

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

从那里获取摘要:

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

名称 最大编码 最大解码 我们能支持多少 byte[] -> byte[] len 使用 -Xmx8G 编码 Java 8 1.62 G 2 G 1.16 G 是 javax.xml 1.62 G 2 G 1.07 G 无 MiGBase64 1.62 G 0.36 G 1.07 G 是 IHarder 1.62 G 0.72 G 1.23 G 是 阿帕奇 0.81 G 0.72 G 0.8 G 是 番石榴 1.62 G 2 G 1.07 G 无 Sun.misc 0.79 G 1.05 G 0.78 G 无

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

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

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

【讨论】:

    【解决方案2】:

    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

    【讨论】:

    • 与我已经使用的处理时间相同,但公共库的功能肯定更多。猜猜这和它一样好,哦,好吧。
    【解决方案3】:

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

    除非您知道自己在做什么,否则我真的不推荐以下内容。

    理想情况下,您要做的是将大量 byte[] 设置为您期望的最大大小,然后通过线程本地或某种池重用此 byte[]

    可惜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)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多