繁体   English   中英

java.nio.charset.Charset.decode(..)/ encode(..)的快速替代品

[英]Fast alternative to java.nio.charset.Charset.decode(..)/encode(..)

有人知道更快的方法来做java.nio.charset.Charset.decode(..) / encode(..)吗?

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

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

这种变化带来了速度的显着降低(以及cpu和mem使用量的显着增加)。

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

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

在进一步阅读我的问题时,似乎这是Charset.encode(..)和decode(..)的已知问题,并且它在Java7中得到解决。 但是,由于某些限制,迁移到Java7对我来说(暂时不是)。

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

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

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

在charset 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总是值得的。

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

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

Charser#newDecoder返回CharsetDecoder ,根据Charset可用于将ByteBufferCharBuffer 主要方法有两种:

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM