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.mzph.cn/news/374842.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java最佳实践–队列之战和链接的ConcurrentHashMap

在使用Java编程语言时&#xff0c;我们将继续讨论与建议的实践有关的系列文章&#xff0c;我们将在四个具有相关语义的流行Queue实现类之间进行性能比较。 为了使事情变得更现实&#xff0c;我们将在多线程环境下进行测试&#xff0c;以讨论和演示如何将ArrayBlockingQueue &am…

关于使用racthet的push.js

racthet的push是用来跳转另外一个页面的效果的。但是必须在服务器的环境下支持。如果想要让本地html访问支持的话需要添加 转载于:https://www.cnblogs.com/djawh/p/4623925.html

“应用程序无法正常启动(oxc000007b)”解决方案

解决方案1 通过“DirectX修复工具 V3.3 标准版”软件修复。 备注&#xff1a;经过测试&#xff0c;并未解决本人的问题&#xff0c;但是这个方法可能对游戏中缺失相关.dll&#xff08;动态链接库&#xff09;有帮助。 解决方案2&#xff1a; 该问题的出现不适偶然&#xff0c;主…

7-15 计算圆周率 (15 分)

根据下面关系式&#xff0c;求圆周率的值&#xff0c;直到最后一项的值小于给定阈值。 输入格式&#xff1a; 输入在一行中给出小于1的阈值。 输出格式&#xff1a; 在一行中输出满足阈值条件的近似圆周率&#xff0c;输出到小数点后6位。 输入样例&#xff1a; 0.01结尾无…

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…

Android特效 五种Toast详解

Toast是Android中用来显示显示信息的一种机制&#xff0c;和Dialog不一样的是&#xff0c;Toast是没有焦点的&#xff0c;而且Toast显示的时间有限&#xff0c;过一定的时间就会自动消失。而且Toast主要用于向用户显示提示消息&#xff0c;接下来巴士为大家总结了Android五种To…

Java最佳实践–高性能序列化

在使用Java编程语言时&#xff0c;我们将继续讨论与建议的实践有关的系列文章&#xff0c;我们将讨论并演示如何将对象序列化用于高性能应用程序。 所有讨论的主题均基于用例&#xff0c;这些用例来自于电信行业的关键任务超高性能生产系统的开发。 在阅读本文的每个部分之前…

7-18 二分法求多项式单根 (20 分)

二分法求函数根的原理为&#xff1a;如果连续函数f(x)在区间[a,b]的两个端点取值异号&#xff0c;即f(a)f(b)<0&#xff0c;则它在这个区间内至少存在1个根r&#xff0c;即f0。 二分法的步骤为&#xff1a; 检查区间长度&#xff0c;如果小于给定阈值&#xff0c;则停止&a…

UITableViewCell 选中的状态小技巧

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {[super setSelected:selected animated:animated]; //cell 没被选中时 隐藏这个 _leftImageViewself.leftImageView.hidden !selected; //选中text变红 不然变灰色self.textLabel.textColor selected ? [UICol…

BZOJ 3143 HNOI2013 游走 高斯消元 期望

这道题是我第一次使用高斯消元解决期望类的问题&#xff0c;首发A了&#xff0c;感觉爽爽的.... 不过笔者在做完后发现了一些问题&#xff0c;在原文的后面进行了说明。 中文题目&#xff0c;就不翻大意了&#xff0c;直接给原题&#xff1a; 一个无向连通图&#xff0c;顶点从…

eclipse启动tomcat, http://localhost:8080无法访问的解决方案

问题:&#xff1a; tomcat在eclipse里面能正常启动&#xff0c;但在浏览器中访问http://localhost:8080/不能访问tomcat管理页面&#xff0c;且报404错误。同时其他项目页面也不能访问。访问的时候出现下列页面: 现在关闭eclipse里面的tomcat&#xff0c;在tomcat安装目录下双击…

洛谷P1014 [NOIP1999 普及组] Cantor 表

现代数学的著名证明之一是 Georg Cantor 证明了有理数是可枚举的。他是用下面这一张表来证明这一命题的&#xff1a; 代码 import java.util.*; public class Main{public static void main(String[] args){//int x1 0;int i 0;Scanner sc new Scanner(System.in);int n s…

3522: [Poi2014]Hotel( 树形dp )

枚举中点x( 即选出的三个点 a , b , c 满足 dist( x , a ) dist( x , b ) dist( x , c ) ) , 然后以 x 为 root 做 dfs , 显然两个位于 x 的同一颗子树内的点是不可能被同时选到的 . 我们对 x 的每一颗子树进行 dfs , 记录下当前子树中的点到 x 距离为 d ( 1 < d < n )…

洛谷P1035 [NOIP2002 普及组] 级数求和

代码 import java.util.Scanner;public class Main {public static void main(String args[]){Scanner sc new Scanner(System.in);int k sc.nextInt();int n 0;double Sn 0;while(Sn<k){n;Sn Sn 1.0/n;}System.out.println(n);} }这样写while循环体这需要每次加上1/…

Java中的Google ClientLogin实用程序

Google API的身份验证和授权是当今需要与Google服务集成和信息交换的应用程序中的常见功能。 尽管大多数Google身份验证过程是针对Web应用程序量身定制的&#xff0c;但它也可用于桌面和已安装的应用程序。 对于桌面应用程序&#xff0c;Google建议使用称为ClientLogin的身份验…

ViewPager使用笔记

1.ViewPager.setCurrentItem(position)&#xff0c;即使已设置动画&#xff0c;但是没有动画效果 原因&#xff1a;因为ViewPager滑动之前的时间间隔太短&#xff0c;可以通过反射&#xff0c;去修改ViewPager自动滑动时间&#xff0c;代码实现如下 1 public class ViewPagerSc…

iOS 8 Xcode6 设置Launch Image 启动图片

本人apem http://www.mamicode.com/info-detail-494411.html 如何设置App的启动图,也就是Launch Image? Step1 1.点击Image.xcassets 进入图片管理,然后右击,弹出"New Launch Image"2.如图,右侧的勾选可以让你选择是否要对ipad,横屏,竖屏,以及低版本的ios系统做支持…

Apache CXF负载平衡和故障转移

前一段时间&#xff0c;我们已经面临基于Apache CXF的负载平衡Web服务客户端的需求。 此外&#xff0c;当某些服务器关闭时&#xff0c;客户端应自动进行故障转移。 更糟糕的是&#xff0c;服务器目标地址列表要从外部服务获取并在运行时更新。 最终&#xff0c;我们最终获得了…

PAT-BASIC-1038-统计同成绩学生

本题要求读入N名学生的成绩&#xff0c;将获得某一给定分数的学生人数输出。 输入格式&#xff1a; 输入在第1行给出不超过105的正整数N&#xff0c;即学生总人数。随后1行给出N名学生的百分制整数成绩&#xff0c;中间以空格分隔。最后1行给出要查询的分数个数K&#xff08;不…