簡體   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