4

任何人都知道更快的方法来做什么java.nio.charset.Charset.decode(..)/做什么encode(..)

它目前是我正在使用的技术的瓶颈之一。

[编辑] 具体来说,在我的应用程序中,我将一个部分从 java 解决方案更改为 JNI 解决方案(因为有一种 C++ 技术比我使用的 Java 技术更适合我的需求)。

此更改导致速度显着下降(以及 cpu 和内存使用量显着增加)。

深入研究我使用的 JNI 解决方案,java 应用程序通过 byte[] 与 C++ 应用程序通信。这些 byte[] 由 Charset.encode(..) 从 java 端生成并传递给 C++ 端。然后,当 C++ 响应带有 byte[] 时,它会在 java 端通过 Charset.decode(..) 进行解码。

对分析器运行此程序,我发现 Charset.decode(..) 和 Charset.encode(..) 与 JNI 解决方案的整个执行时间相比都花费了相当长的时间(我只分析了 JNI 解决方案,因为这是我可以很快完成的事情。一旦我腾出我的日程安排,我将在以后的日期对整个应用程序进行概要分析:-))。

在进一步阅读我的问题后,它似乎是 Charset.encode(..) 和 decode(..) 的一个已知问题,它正在 Java7 中得到解决。但是,由于一些限制,迁移到 Java7 对我来说不是一个选择(目前)。

这就是为什么我在这里问是否有人知道 Java5 解决方案/替代方案(对不起,应该提到这是针对 Java5 的)?:-)

4

3 回答 3

6

javadoc forencode()decode()清楚地表明这些是便利方法。例如,对于encode()

将 Unicode 字符编码为此字符集中的字节的便捷方法。

在字符集 cs 上调用此方法返回与表达式相同的结果

 cs.newEncoder()
   .onMalformedInput(CodingErrorAction.REPLACE)
   .onUnmappableCharacter(CodingErrorAction.REPLACE)
   .encode(bb); 

除了它可能更有效,因为它可以在连续调用之间缓存编码器。

那里的语言有点模糊,但不使用这些便捷方法可能会提高性能。一次创建和配置编码器,然后重新使用它:

 CharsetEncoder encoder = cs.newEncoder()
   .onMalformedInput(CodingErrorAction.REPLACE)
   .onUnmappableCharacter(CodingErrorAction.REPLACE);

 encoder.encode(...);
 encoder.encode(...);
 encoder.encode(...);
 encoder.encode(...);

阅读 javadoc 总是值得的,即使您认为自己已经知道答案。

于 2010-01-20T00:04:07.500 回答
2

第一部分 - 通常将数组传递给 JNI 代码是个坏主意。由于 GC,Java 必须复制数组。在值得的情况下,数组将被复制两次——在 JNI 代码的路上和回来的路上:)

因为Buffer引入了类层次结构。当然,Java 开发团队创造了一种编码/解码字符的好方法:

Charser#newDecoder返回您CharsetDecoder,可用于ByteBuffer根据CharBuffera 转换为Charset. 有两个主要的方法版本:

CoderResult decode(ByteBuffer in, CharBuffer out, boolean endOfInput)
CharBuffer decode(ByteBuffer in)

为了获得最大性能,您需要第一个。它内部没有隐藏的内存分配。

您需要注意编码器/解码器可以维护内部状态,所以要小心(例如,如果您从 2 字节编码映射并且输入缓冲区有一半的字符......)。编码器/解码器也不是线程安全的

于 2013-01-09T09:53:05.220 回答
1

在字节数组中“挤压”字符串的理由很少。我建议编写 C 函数以将 utf-16 字符串作为参数。这样就不需要任何转换。

于 2010-01-21T09:42:29.147 回答