Java最佳實踐– Char到Byte和Byte到Char的轉換

在使用Java編程語言時,我們將繼續討論與建議的實踐有關的系列文章,我們將討論String性能調優。 特別是,我們將重點介紹使用默認編碼時如何有效地處理字符到字節和字節到字符的轉換。 本文總結了兩種提議的自定義方法與兩種經典方法(“ String.getBytes() ”和NIO ByteBuffer )的性能比較, 后者將字符轉換為字節,反之亦然。

所有討論的主題均基于用例,這些用例來自于電信行業的關鍵任務超高性能生產系統的開發。

在閱讀本文的每個部分之前,強烈建議您參考相關的Java API文檔以獲取詳細信息和代碼示例。

所有測試均針對具有以下特征的Sony Vaio進行:

  • 系統:openSUSE 11.1(x86_64)
  • 處理器(CPU):Intel(R)Core(TM)2 Duo CPU T6670 @ 2.20GHz
  • 處理器速度:1,200.00 MHz
  • 總內存(RAM):2.8 GB
  • Java:OpenJDK 1.6.0_0 64位

應用以下測試配置:

  • 并發工作者線程數:1
  • 每個工作者的測試重復次數:1000000
  • 整體測試次數:100

字符到字節和字節到字符的轉換
字符到字節和字節到字符的轉換被認為是Java開發人員的常見任務,這些開發人員正在針對網絡環境進行編程,處理字節數據流,序列化String對象,實現通信協議等。因此,Java提供了一些實用程序來啟用開發人員將String (或字符數組)轉換為等效的字節數組,反之亦然。

String類的“ getBytes(charsetName) ”操作可能是將String轉換為其等效的字節數組的最常用方法。 由于可以根據所使用的編碼方案來不同地表示每個字符,因此,上述操作需要“ charsetName ”以便正確轉換String字符也就不足為奇了。 如果未提供“ charsetName ”,則該操作使用平臺的默認字符集將String編碼為字節序列。

將字符數組轉換為其等效字節數組的另一種“經典”方法是使用NIO包的ByteBuffer類。 稍后將提供特定方法的示例代碼片段。

與更細粒度的方法相比,上述兩種方法雖然非常流行并且毫無爭議地易于使用和直接使用,但它們的性能都大大不足。 請記住, 我們不是在字符編碼之間進行轉換 。 為了在字符編碼之間進行轉換,您應該使用“ String.getBytes(charsetName) ”或NIO框架方法和實用程序來使用“經典”方法。

當所有要轉換的字符均為ASCII字符時,建議的轉換方法如下所示:

public static byte[] stringToBytesASCII(String str) {char[] buffer = str.toCharArray();byte[] b = new byte[buffer.length];for (int i = 0; i < b.length; i++) {b[i] = (byte) buffer[i];}return b;
}

通過將每個字符值轉換為等效的字節來構造結果字節數組,因為我們知道所有字符都在ASCII范圍內(0 – 127),因此只能占據一個 字節大小。

使用結果字節數組,我們可以通過使用“經典” 字符串構造函數“ new String(byte []) ”轉換回原始String 。

對于默認的字符編碼,我們可以使用下面顯示的方法將String轉換為字節數組,反之亦然:

public static byte[] stringToBytesUTFCustom(String str) {char[] buffer = str.toCharArray();byte[] b = new byte[buffer.length << 1];for(int i = 0; i < buffer.length; i++) {int bpos = i << 1;b[bpos] = (byte) ((buffer[i]&0xFF00)>>8);b[bpos + 1] = (byte) (buffer[i]&0x00FF);}return b;
}

Java中的每種字符類型都占用2個字節的大小。 為了將String轉換為等效的字節數組,我們將String的每個字符轉換為其2字節表示形式。

使用結果字節數組,我們可以使用以下提供的方法將其轉換回原始的String :

public static String bytesToStringUTFCustom(byte[] bytes) {char[] buffer = new char[bytes.length >> 1];for(int i = 0; i < buffer.length; i++) {int bpos = i << 1;char c = (char)(((bytes[bpos]&0x00FF)<<8) + (bytes[bpos+1]&0x00FF));buffer[i] = c;}return new String(buffer);
}

我們從其2字節表示形式構造每個String字符。 使用結果字符數組,我們可以通過使用“經典” 字符串構造函數“ new String(char []) ”將其轉換回原始String 。

最后但并非最不重要的一點是,我們提供了兩個使用NIO包的示例方法,以便將String轉換為其等效的字節數組,反之亦然:

public static byte[] stringToBytesUTFNIO(String str) {char[] buffer = str.toCharArray();byte[] b = new byte[buffer.length << 1];CharBuffer cBuffer = ByteBuffer.wrap(b).asCharBuffer();for(int i = 0; i < buffer.length; i++)cBuffer.put(buffer[i]);return b;
}
public static String bytesToStringUTFNIO(byte[] bytes) {CharBuffer cBuffer = ByteBuffer.wrap(bytes).asCharBuffer();return cBuffer.toString();
}

對于本文的最后一部分,我們提供了上述字符串到字節數組和字節數組到字符串轉換方法的性能比較表。 我們已經使用輸入字符串“ test string ”測試了所有方法。

首先將String轉換為字節數組的性能比較表:

橫軸表示測試運行的次數,縱軸表示每次測試運行的每秒平均事務數(TPS)。 因此,較高的值更好。 不出所料,與“ stringToBytesASCII(String) ”和“ stringToBytesUTFCustom(String) ”建議的方法相比,“ String.getBytes() ”和“ stringToBytesUTFNIO(String) ”方法的執行效果均較差。 如您所見,與“經典”方法相比,我們提出的方法可將TPS提高近30%。

最后將字節數組轉換為String的性能對比圖:

橫軸表示測試運行的次數,縱軸表示每次測試運行的每秒平均事務數(TPS)。 因此,較高的值更好。 不出所料,與“ bytesToStringUTFCustom(byte []) ”建議的方法相比,“ new String(byte []) ”和“ bytesToStringUTFNIO(byte []) ”方法的執行效果均較差。 如您所見,與“ new String(byte []) ”方法相比,我們提出的方法使TPS增長了近15%,與“ bytesToStringUTFNIO(byte []) ”方法相比,TPS增長了近30%。

總之,當您處理字符到字節或字節到字符的轉換,而又不想更改所使用的編碼時,可以通過使用自定義(細粒度)方法而不是使用提供的“經典”方法來獲得卓越的性能。 String類和NIO包。 當將測試字符串轉換為等效的字節數組時,與“經典”方法相比,我們提出的方法總體上提高了45%的性能。

快樂編碼

賈斯汀

聚苯乙烯

考慮到我們的一些讀者提出的使用“ String.charAt(int) ”操作而不是使用“ String.toCharArray() ”來將String字符轉換為字節的主張后,我更改了我們提出的方法,并重新執行測試。 如預期的那樣,進一步實現了性能提升。 特別地,在TPS 額外 13%的平均增加被記錄為“stringToBytesASCII(字符串)”方法和TPS的額外 2%平均增加被記錄為“stringToBytesUTFCustom(字符串)”。 因此,您應該使用更改后的方法,因為它們的性能甚至比原始方法還要好。 更新的方法如下所示:

public static byte[] stringToBytesASCII(String str) {byte[] b = new byte[str.length()];for (int i = 0; i < b.length; i++) {b[i] = (byte) str.charAt(i);}return b;
}
public static byte[] stringToBytesUTFCustom(String str) {byte[] b = new byte[str.length() << 1];for(int i = 0; i < str.length(); i++) {char strChar = str.charAt(i);int bpos = i << 1;b[bpos] = (byte) ((strChar&0xFF00)>>8);b[bpos + 1] = (byte) (strChar&0x00FF); }return b;
}
相關文章 :
  • Java最佳實踐–多線程環境中的DateFormat
  • Java最佳實踐–高性能序列化
  • Java最佳實踐– Vector vs ArrayList vs HashSet
  • Java最佳實踐–字符串性能和精確字符串匹配
  • Java最佳實踐–隊列之戰和鏈接的ConcurrentHashMap

翻譯自: https://www.javacodegeeks.com/2010/11/java-best-practices-char-to-byte-and.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/374842.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374842.shtml
英文地址,請注明出處:http://en.pswp.cn/news/374842.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

IOS-C文件的創建于初始化函數.void init() write_file()

//文件初始化 void init(){ FILE * fpNULL; fpfopen("telbook.data", "rb"); int count0; if (fpNULL) //沒有這個文件就把這個文件創建出來 { fpfopen("tellbook.data", "wb"); fwrite(&count, sizeof(count), 1, fp); fclose(…

7-3 逆序的三位數 (10 分)

7-3 逆序的三位數 (10 分) 程序每次讀入一個正3位數&#xff0c;然后輸出按位逆序的數字。注意&#xff1a;當輸入的數字含有結尾的0時&#xff0c;輸出不應帶有前導的0。比如輸入700&#xff0c;輸出應該是7。 輸入格式&#xff1a; 每個測試是一個3位的正整數。 輸出格式&a…

拋棄優啟Grub4dos和PE大多數時間可以這樣用

拋棄優啟Grub4dos和PE大多數時間可以這樣用 在能夠進入Windows的情況下&#xff0c;Grub4dos和PE大多數時間可以這樣用 http://yunpan.cn/cyuuUtUQMfmGN 提取碼 c2acGrub4dos的出現顛覆了傳統的EZBOOT光盤啟動模式&#xff0c;很多人用grub4dos來實現優盤啟動&#xff0c;同時g…

Java最佳實踐–隊列之戰和鏈接的ConcurrentHashMap

在使用Java編程語言時&#xff0c;我們將繼續討論與建議的實踐有關的系列文章&#xff0c;我們將在四個具有相關語義的流行Queue實現類之間進行性能比較。 為了使事情變得更現實&#xff0c;我們將在多線程環境下進行測試&#xff0c;以討論和演示如何將ArrayBlockingQueue &am…

HDU 5652 India and China Origins(二分 + BFS)

本文鏈接:http://www.cnblogs.com/Ash-ly/p/5398867.html 題意&#xff1a; 中國和印度之間有一片地方&#xff0c;把這片地方抽象化&#xff0c;于是就可以看成一個N * M矩陣&#xff0c;其中黑色的代表高山不能走過去&#xff0c;白色的代表平原&#xff0c;可以通行,人每次可…

C語言%.2f四舍五入

#include <stdio.h> int main() {double d 1.199;printf("%.2f", d);return 0; }輸出1.20 如果不想讓其四舍五入可以這樣&#xff1a; #include <stdio.h> #include <math.h> int main() {double d 1.199;printf("%.2f", floor(d * 1…

關于使用racthet的push.js

racthet的push是用來跳轉另外一個頁面的效果的。但是必須在服務器的環境下支持。如果想要讓本地html訪問支持的話需要添加 轉載于:https://www.cnblogs.com/djawh/p/4623925.html

休眠自動提交命令強制MySQL在過多的磁盤I / O中運行

親愛的大家&#xff0c; 我敢肯定&#xff0c;你們中的許多人都在使用Hibernate和MySQL&#xff0c;我自己在這里和那里都使用它。 通常&#xff0c;編程模型是不錯的&#xff0c;但是普通的JDBC可以快很多已經不是什么秘密了。 在這篇文章中&#xff0c;我想引起您的注意Hibe…

“應用程序無法正常啟動(oxc000007b)”解決方案

解決方案1 通過“DirectX修復工具 V3.3 標準版”軟件修復。 備注&#xff1a;經過測試&#xff0c;并未解決本人的問題&#xff0c;但是這個方法可能對游戲中缺失相關.dll&#xff08;動態鏈接庫&#xff09;有幫助。 解決方案2&#xff1a; 該問題的出現不適偶然&#xff0c;主…

Linux: dev: cmake: CHECK_LIBRARY_EXISTS

文章目錄 簡介例子源代碼最終調用到的兩個命令如果結果是這里為什么不直接使用rpm查看包呢&#xff1f;需要注意的問題 簡介 https://cmake.org/cmake/help/latest/module/CheckLibraryExists.html 這個方法是在Modules/CheckLibraryExists.cmake文件里定義的一個宏。 最終使用…

7-15 計算圓周率 (15 分)

根據下面關系式&#xff0c;求圓周率的值&#xff0c;直到最后一項的值小于給定閾值。 輸入格式&#xff1a; 輸入在一行中給出小于1的閾值。 輸出格式&#xff1a; 在一行中輸出滿足閾值條件的近似圓周率&#xff0c;輸出到小數點后6位。 輸入樣例&#xff1a; 0.01結尾無…

Struts2的全局結果視圖的配置

1.在struts.xml中的package標簽內添加<global-results/>標簽&#xff0c;將全局結果加進該標簽內&#xff0c;只適用于當前包下。 <package name"customer" namespace"/customer" extends"struts-default" > <global-results>…

長大了Java! 提出Java桌面版

不&#xff0c;這不是另一個“ Java已死”的咆哮。 Java非常活躍。 它是可用的最佳開發和運行時平臺之一。 迄今為止&#xff0c;最穩定的平臺。 那可能只是它最大的禍根。 荒謬&#xff01; 穩定性如何&#xff1f; 你可能會問。 好吧&#xff0c;由于它&#xff0c;您可以看到…

[算法練習]Excel Sheet Column Title

題目&#xff1a; Given a positive integer, return its corresponding column title as appear in an Excel sheet. For example: 1 -> A 2 -> B 3 -> C ... 26 -> Z 27 -> AA 28 -> AB 代碼&#xff1a; class Solution { public: string convertToTitle(…

7-16 求符合給定條件的整數集 (15 分)

給定不超過6的正整數A&#xff0c;考慮從A開始的連續4個數字。請輸出所有由它們組成的無重復數字的3位數。 輸入格式&#xff1a; 輸入在一行中給出A。 輸出格式&#xff1a; 輸出滿足條件的的3位數&#xff0c;要求從小到大&#xff0c;每行6個整數。整數間以空格分隔&#…

JUnit學習之hamcrest、testSuite介紹及測試原則

[轉自] http://huihai.iteye.com/blog/1994270 上一節說了junit的一些基本概念&#xff0c;主要使用assert做一些基本的判斷。但很多時候使用assert做判斷&#xff0c;并不方便&#xff0c;如果要判斷某幾個值是否為true或false&#xff0c;這時使用hamcrest來判斷就會方便許多…

Java最佳實踐– Vector vs ArrayList vs HashSet

在使用Java編程語言時&#xff0c;我們將繼續討論與建議的實踐有關的系列文章&#xff0c;我們將在三個最常用的Collection實現類之間進行性能比較。 為了使事情變得更現實&#xff0c;我們將在多線程環境下進行測試&#xff0c;以討論和演示如何將Vector &#xff0c; ArrayLi…

iOS:圖片上傳時兩種圖片壓縮方式的比較

上傳圖片不全面的想法&#xff1a;把圖片保存到本地,然后把圖片的路徑上傳到服務器&#xff0c;最后又由服務器把路徑返回&#xff0c;這種方式不具有擴展性&#xff0c;如果用戶換了手機&#xff0c;那么新手機的沙盒中就沒有服務器返回的圖片路徑了&#xff0c;此時就無法獲取…

7-17 爬動的蠕蟲 (15 分)

一條蠕蟲長1寸&#xff0c;在一口深為N寸的井的底部。已知蠕蟲每1分鐘可以向上爬U寸&#xff0c;但必須休息1分鐘才能接著往上爬。在休息的過程中&#xff0c;蠕蟲又下滑了D寸。就這樣&#xff0c;上爬和下滑重復進行。請問&#xff0c;蠕蟲需要多長時間才能爬出井&#xff1f;…

淺談泛型之泛型方法

實際不用多說只舉2個例子就行: //例1 static void fromArrayToCollection(Object[] a, Collection<?> c) {for (Object o : a) { c.add(o); // 編譯錯誤,錯誤原因也很簡單,<?>是無上下界的通配符泛型,所以編譯器根本無法確認類型} } //例2 static <T> void…