实践中的重构11_茴香豆的多种写法
鲁迅先生的名文孔乙己中,孔乙己纠结于茴香豆的茴字有多种写法,可惜小孩子不愿意学,可惜了孔乙己的一片良苦用心。
一个功能,不同的程序员的实现,基于各种因素,可能是千差万别的。即使是同一个程序员,一般也会有多种方式来完成该程序的编写。面对各种不同的可能实现方式,挑选出适合当前场景的实现,就变成了程序员责无旁贷的任务。
/** * 这个是最早的程序版本,把一个字符串转换成一个16进制编码的字符串。 * 看到这段代码的时候,第一反应是怎么不用StringBuilder。而是字符串相加。 * 其次,这个是一个常用的工具类,每天的调用量很大,性能看上去不怎么好。 * */ public static String str2HexString_0(String str) { String ret = ""; byte[] b = str.getBytes();
for (int i = 0; i < b.length; i++) { String hex = Integer.toHexString(b[i] & 0xFF);
if (hex.length() == 1) { hex = '0' + hex; }
ret += hex.toUpperCase(); }
return ret; }
/** * 第一次尝试修改。核心思想是用StringBuilder代替String。展开数字对String的转换,避免调用toUpperCase方法。 * */ public static String str2HexString_1(String str) {
StringBuilder sb = new StringBuilder(str.length() << 1);
byte[] data = str.getBytes();
for (int i = 0; i < data.length; i++) {
int left = (data[i] & 0xF0) >> 4; append(sb, left);
int right = data[i] & 0x0F; append(sb, right);
}
return sb.toString(); }
private static void append(StringBuilder sb, int i) { switch (i) { case 0: sb.append("0"); break; case 1: sb.append("1"); break; case 2: sb.append("2"); break; case 3: sb.append("3"); break; case 4: sb.append("4"); break; case 5: sb.append("5"); break; case 6: sb.append("6"); break; case 7: sb.append("7"); break; case 8: sb.append("8"); break; case 9: sb.append("9"); break; case 10: sb.append("A"); break; case 11: sb.append("B"); break; case 12: sb.append("C"); break; case 13: sb.append("D"); break; case 14: sb.append("E"); break; case 15: sb.append("F"); break; default: break; } }
/** * 测试发现,第一次的修改速度提高了。但是code变长了,看起来不是很舒服。 想了想不用switch是可以提高code的简洁程度的。 * 于是有了第2次修改。 * */ public static String str2HexString_2(String str) {
StringBuilder sb = new StringBuilder(str.length() << 1);
byte[] data = str.getBytes();
for (int i = 0; i < data.length; i++) {
int left = (data[i] & 0xF0) >> 4; sb.append("0123456789ABCDEF".charAt(left));
int right = data[i] & 0x0F; sb.append("0123456789ABCDEF".charAt(right));
}
return sb.toString(); }
/** 想了想用数组不用charAt会不会更快呢。于是有了下面的版本。 */ public static String str2HexString_3(String str) {
StringBuilder sb = new StringBuilder(str.length() << 1);
byte[] data = str.getBytes();
for (int i = 0; i < data.length; i++) {
int left = (data[i] & 0xF0) >> 4; sb.append(digit2string[left]);
int right = data[i] & 0x0F; sb.append(digit2string[right]);
}
return sb.toString(); }
private static final String[] digit2string = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", };
/** * 测试发现第3次修改的性能不怎么样。而且code不易读了。算是一个失败的修改。 * 出去抽了一根烟,突然醒悟到为什么一定要用StringBuilder呢, * 这个程序实质上就是一个对数据的操作。既然是对数据的操作,那就直接操作数据好了。干嘛要多绕一圈呢。 于是有了下面的版本。 * */ public static String str2HexString_4(String str) {
byte[] oldData = str.getBytes(); char[] tmpData = new char[oldData.length << 1];
for (int i = 0; i < oldData.length; i++) { int left = (oldData[i] & 0xF0) >> 4; tmpData[i << 1] = "0123456789ABCDEF".charAt(left);
int right = oldData[i] & 0x0F; tmpData[(i << 1) + 1] = "0123456789ABCDEF".charAt(right); } return new String(tmpData); }
/** 网友gdpglc的思路.*/ public static String str2HexString_5(String str) {
byte[] oldData = str.getBytes(); char[] tmpData = new char[oldData.length << 1];
for (int i = 0; i < oldData.length; i++) { int left = (oldData[i] & 0xF0) >> 4; tmpData[i << 1] = digit2char[left];
int right = oldData[i] & 0x0F; tmpData[(i << 1) + 1] = digit2char[right]; } return new String(tmpData); }
private static final char[] digit2char = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', };
/** * 返回一个随机的字符串。150是基于该程序使用场景的抽样得到的长度。 * */ private static String getRandomString() { StringBuilder sb = new StringBuilder(); Random r = new Random(); int length = 150 + r.nextInt(50); for (int i = 0; i < length; i++) { sb.append('a' + r.nextInt(26)); } return sb.toString(); }
/** * 随机单元测试。 结果见perfResult.txt。 * * */ @Test public void test() { for (int i = 0; i < 100; i++) { String inputString = getRandomString(); String result_0 = str2HexString_0(inputString); String result_1 = str2HexString_1(inputString); String result_2 = str2HexString_2(inputString); String result_3 = str2HexString_3(inputString); String result_4 = str2HexString_4(inputString); String result_5 = str2HexString_5(inputString); Assert.assertEquals(result_0, result_1); Assert.assertEquals(result_1, result_2); Assert.assertEquals(result_2, result_3); Assert.assertEquals(result_3, result_4); Assert.assertEquals(result_4, result_5); Assert.assertEquals(result_5, result_0); } }
性能结果报告:
100000次执行的性能结果。
单位ms。
str2HexString_0 132016
str2HexString_1 8906
str2HexString_2 5297
str2HexString_3 7859
str2HexString_4 4203
str2HexString_5 3985
实践中的重构11_茴香豆的多种写法相关推荐
- 实践中的重构19_脱裤子放屁
每当看到代码中有一个明显的冗余的时候,我就有一个感慨,这家伙时间真多啊,放个屁还要脱裤子. 看例子. if (addressCode != null && (StringUtil.eq ...
- 实践提高《重构改善既有代码的设计第2版》PDF中文+PDF英文+对比分析
重构是编程的基础,是在不改变外部行为的前提下,有条不紊地改善代码.编程爱好者都知道,Martin Fowler 的<重构:改善既有代码的设计>已经成为全球有经验的程序员手中的利器,既可用来 ...
- 从这些企业的数字化转型实践中,你能得到什么启发
随着成本高涨.网络冲击.消费升级转型等多种因素的冲击,近几年来,我国传统零售业遭遇了前所未有的寒冬. 三年前,有媒体是这样形容零售百货业发展现状与趋势: "舞榭歌台,风流总被雨打风吹去.&q ...
- 复旦肖仰华:领域知识图谱落地实践中的问题与对策
肖仰华博士,复旦大学计算机科学与技术学院教授,博士生导师,知识工场实验室负责人. 报告摘要:近年来,知识图谱技术进展迅速,各种领域知识图谱技术在很多领域或行业取得了显著落地效果.在领域知识图谱技术的落 ...
- 产业AI实践中,如何有效提升图像识别精度、实现极小目标检测? | 百度AI公开课报名...
位来 发自 凹非寺 量子位 报道 | 公众号 QbitAI 目前,各个企业行业在AI落地应用中,常常会遇到极小目标检测问题. 如工业质检场景中对轴承.喷油嘴等精密金属部件的细微缺陷检测:电力巡检场景在 ...
- 【机器学习】机器学习实践中的 7 种常见错误
编译:伯乐在线 - yixingqingkong,英文:Cheng-Tao Chu 编注:本文作者是 Codecademy 的分析主管 Cheng-Tao Chu,其专长是数据挖掘和机器学习,之前在 ...
- 深度长文 | 复旦大学肖仰华:领域知识图谱落地实践中的问题与对策
报告摘要:近年来,知识图谱技术进展迅速,各种领域知识图谱技术在很多领域或行业取得了显著落地效果.在领域知识图谱技术的落地实践过程中涌现出一大批理论与工程问题.本报告结合复旦大学知识工场实验室十多个领域 ...
- 肖仰华 | 领域知识图谱落地实践中的问题与对策
本文转载自公众号:知识工场. 肖仰华教授2万字长文为您深度剖析领域知识图谱,对领域知识图谱技术与落地应用中的一系列关键问题做了系统的梳理与解答. 肖仰华博士,复旦大学计算机科学与技术学院教授,博士生导 ...
- 机器学习与R语言(原书第2版)》一1.4 实践中的机器学习
本节书摘来自华章出版社<机器学习与R语言(原书第2版)>一书中的第1章,第1.4节,美] 布雷特·兰茨(Brett Lantz) 著,李洪成 许金炜 李舰 译更多章节内容可以访问云栖社区& ...
最新文章
- 看过来,包邮送AirPods Pro!
- 1562. [NOI2009]变换序列【二分图】
- IO模型之非阻塞IO
- codevs 1183 泥泞的道路 二分+SPFA最长路
- java optional 用法_Java 8中的Optional: 如何正确使用?
- html5 数据验证,【译】表单数据校验
- C#处理JSON 数据
- NBT | 微生物研究所王军组在AI赋能挖掘微生物组功能多肽方面获得新进展
- MyBatis学习总结(2)——使用MyBatis对表执行CRUD操作
- 吴恩达机器学习7——支持向量机SVM
- centos7安装rabbitmq 总结
- Tomcat下WebSocket最大连接数测试
- [ openwrt ] 添加一个通过GPIO控制的LED
- CVPR 2020 | 旷视研究院提出优化领域自适应物体检测性能的类别正则化框架
- 无线电波是怎么产生的
- 《树莓派Python编程入门与实战》——2.3 使用Raspbian图形用户界面
- easyexcel官方地址
- layui数据表格中包含图片的处理方式
- 自主创新持续领航,麒麟信安荣获“网信自主创新尖峰企业”称号
- 大数据领域十大必读书籍