- 浏览: 525257 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
飞天奔月:
public List<String> gener ...
实践中的重构30_不做油漆匠 -
在世界的中心呼喚愛:
在世界的中心呼喚愛 写道public class A {
...
深入理解ReferenceQueue GC finalize Reference -
在世界的中心呼喚愛:
在世界的中心呼喚愛 写道在世界的中心呼喚愛 写道在classB ...
深入理解ReferenceQueue GC finalize Reference -
在世界的中心呼喚愛:
在世界的中心呼喚愛 写道在classB的finalize上打断 ...
深入理解ReferenceQueue GC finalize Reference -
在世界的中心呼喚愛:
iteye比较少上,如果可以的话,可以发e-mail交流:ch ...
深入理解ReferenceQueue GC finalize Reference
鲁迅先生的名文孔乙己中,孔乙己纠结于茴香豆的茴字有多种写法,可惜小孩子不愿意学,可惜了孔乙己的一片良苦用心。
一个功能,不同的程序员的实现,基于各种因素,可能是千差万别的。即使是同一个程序员,一般也会有多种方式来完成该程序的编写。面对各种不同的可能实现方式,挑选出适合当前场景的实现,就变成了程序员责无旁贷的任务。
性能结果报告:
100000次执行的性能结果。
单位ms。
str2HexString_0 132016
str2HexString_1 8906
str2HexString_2 5297
str2HexString_3 7859
str2HexString_4 4203
str2HexString_5 3985
那为什么eclipse里边的右键菜单里的重构功能,包括了改类名、改方法名等等...
改名太没技术含量啦,直接忽略
就像eclipse自动生成get、set,也能叫写代码?
get set 是javabean的规范,你在这里说eclipse...
不想和你争论什么叫技术含量,我只希望我的代码,不会给后来人带来麻烦... 其实也包括我自已,因为我记不住两周以前写的代码,需要修改就得重看代码。
你不经意见好象说了一句真话。你自已写个文档试试别人能不能看懂就知道了...
那为什么eclipse里边的右键菜单里的重构功能,包括了改类名、改方法名等等...
改名太没技术含量啦,直接忽略
就像eclipse自动生成get、set,也能叫写代码?
那为什么eclipse里边的右键菜单里的重构功能,包括了改类名、改方法名等等...
HashMap 采用的是散列表,散列表是用一个复杂的算法定位元素,而数组,是在一个连续的地址空间里,通过简单的地址记算查找元素,你的结论是怎么得出来的,要不要象楼主一样,做做测试,用数据说话。
乘2写成<<1 其实我也经常这样写,如果追求性能的话呵呵,但是就是可读性差很多,可能需要注释下
hashMap性能不好。用hashMap还不如用switch
没错,这个是一个潜在的bug,这个是在早期架构的时候,目光有局限性。
一直以来,所有部署的机器都是同一个默认字符集,所以用部署的方法弥补了这个问题。
系统中所有编码相关的地方基本上都有这个问题。
算是一个简单的编码,和base64相似,但是没有base64紧凑。
你的改法和我的方法3没有本质区别,但是性能结果不理想。
这个过程也许有一点点过。但是反重构我是不同意的。
软件本身就不是一个简单的事情。看到<<或者>>如果你觉得不舒服我只能说个人的理解不一样。
这个类一看就知道应该是底层协议用的,当然是比较底层的。
1)"0123456789ABCDEF".charAt(left)
2)char[] chs={'0','1'........'F'}
charAt源码:
public char charAt(int index) {
if ((index < 0) || (index >= count)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index + offset];
}
这两行代码的效率是不一样的。因为1)的代码比2)的代码多了一个方法调用、参数传递还有里边判断的过程。
这个的底层协议,导致数据长度比原来增加了一倍,这个方案本身就是粗糙的,然后拼命的提高代码效率...
个人喜好吧
我说了和3本质是一样的,麻烦能不能看看3.
一个功能,不同的程序员的实现,基于各种因素,可能是千差万别的。即使是同一个程序员,一般也会有多种方式来完成该程序的编写。面对各种不同的可能实现方式,挑选出适合当前场景的实现,就变成了程序员责无旁贷的任务。
/** * 这个是最早的程序版本,把一个字符串转换成一个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
评论
27 楼
gdpglc
2010-12-29
gtssgtss 写道
gdpglc 写道
gtssgtss 写道
这不是重构,这是优化
消除重复代码与消除临时变量才是重构
消除重复代码与消除临时变量才是重构
那为什么eclipse里边的右键菜单里的重构功能,包括了改类名、改方法名等等...
改名太没技术含量啦,直接忽略
就像eclipse自动生成get、set,也能叫写代码?
get set 是javabean的规范,你在这里说eclipse...
不想和你争论什么叫技术含量,我只希望我的代码,不会给后来人带来麻烦... 其实也包括我自已,因为我记不住两周以前写的代码,需要修改就得重看代码。
gtssgtss 写道
。。。原来大家认为文学水平也算计算机水平么。。。
你不经意见好象说了一句真话。你自已写个文档试试别人能不能看懂就知道了...
26 楼
gtssgtss
2010-12-29
。。。原来大家认为文学水平也算计算机水平么。。。
25 楼
zhang_xzhi_xjtu
2010-12-29
改名太没技术含量!
老大难问题,名字一直都是一个系统清晰的关键。
老大难问题,名字一直都是一个系统清晰的关键。
24 楼
gtssgtss
2010-12-29
gdpglc 写道
gtssgtss 写道
这不是重构,这是优化
消除重复代码与消除临时变量才是重构
消除重复代码与消除临时变量才是重构
那为什么eclipse里边的右键菜单里的重构功能,包括了改类名、改方法名等等...
改名太没技术含量啦,直接忽略
就像eclipse自动生成get、set,也能叫写代码?
23 楼
gdpglc
2010-12-28
gtssgtss 写道
这不是重构,这是优化
消除重复代码与消除临时变量才是重构
消除重复代码与消除临时变量才是重构
那为什么eclipse里边的右键菜单里的重构功能,包括了改类名、改方法名等等...
22 楼
gtssgtss
2010-12-28
这不是重构,这是优化
消除重复代码与消除临时变量才是重构
消除重复代码与消除临时变量才是重构
21 楼
zhang_xzhi_xjtu
2010-12-28
可读性因人而异,性能可以用数据说话。
20 楼
gdpglc
2010-12-28
tcgdy0201 写道
用hashmap代替数组,无论是代码可读性还是效率都比数组高
HashMap 采用的是散列表,散列表是用一个复杂的算法定位元素,而数组,是在一个连续的地址空间里,通过简单的地址记算查找元素,你的结论是怎么得出来的,要不要象楼主一样,做做测试,用数据说话。
19 楼
tcgdy0201
2010-12-28
用hashmap代替数组,无论是代码可读性还是效率都比数组高
18 楼
kinjo
2010-12-24
gdpglc 写道
"0123456789ABCDEF".charAt(left)
地方还可以优化
char[] chs={'0','1'........'F'}
chs[left]
不过我一定不会这么用。我宁可用Character.forDigit方法,这样的代码可读性太差了。这么在乎性能的理由是什么?你在写系统软件吗?
把乘2写成<<1,唉。我觉得真是精力过剩了..........
这哪能叫重构.... 整个一个反重构
地方还可以优化
char[] chs={'0','1'........'F'}
chs[left]
不过我一定不会这么用。我宁可用Character.forDigit方法,这样的代码可读性太差了。这么在乎性能的理由是什么?你在写系统软件吗?
把乘2写成<<1,唉。我觉得真是精力过剩了..........
这哪能叫重构.... 整个一个反重构
乘2写成<<1 其实我也经常这样写,如果追求性能的话呵呵,但是就是可读性差很多,可能需要注释下
17 楼
mfkvfn
2010-12-20
peak 写道
switch 这个方法用的实在是太丑陋了,换成一个hashmap,每次传进一个key取value多好啊
hashMap性能不好。用hashMap还不如用switch
16 楼
zhmiao
2010-12-20
写的真是不错,这几天正好也需要用到。
15 楼
peak
2010-12-20
switch 这个方法用的实在是太丑陋了,换成一个hashmap,每次传进一个key取value多好啊
14 楼
zhang_xzhi_xjtu
2010-12-19
gdpglc 写道
这个代码存在一个潜在的bug。
byte[] data = str.getBytes();
这行代码。String的getBytes方法是和当前java程序的默认字符集相关的。
我想编码的东西最终还是要还原的,如果还原时的字符集和编码时的不同,则会产生乱码。
byte[] data = str.getBytes();
这行代码。String的getBytes方法是和当前java程序的默认字符集相关的。
我想编码的东西最终还是要还原的,如果还原时的字符集和编码时的不同,则会产生乱码。
没错,这个是一个潜在的bug,这个是在早期架构的时候,目光有局限性。
一直以来,所有部署的机器都是同一个默认字符集,所以用部署的方法弥补了这个问题。
系统中所有编码相关的地方基本上都有这个问题。
13 楼
gdpglc
2010-12-18
这个代码存在一个潜在的bug。
byte[] data = str.getBytes();
这行代码。String的getBytes方法是和当前java程序的默认字符集相关的。
我想编码的东西最终还是要还原的,如果还原时的字符集和编码时的不同,则会产生乱码。
byte[] data = str.getBytes();
这行代码。String的getBytes方法是和当前java程序的默认字符集相关的。
我想编码的东西最终还是要还原的,如果还原时的字符集和编码时的不同,则会产生乱码。
12 楼
faye.feelcool
2010-12-18
本来就是一个茴字怎么写的,纯技术的讨论。
不过我补充一句:不管是可读性,和高性能都是有目的的,如果你所谓目的的前提不存在,所作的一切都是枉然。
就像我花5元要碗牛肉面,你给我满汉全席,我不会不好意思,但我不会多给你超过5元钱。
不过我补充一句:不管是可读性,和高性能都是有目的的,如果你所谓目的的前提不存在,所作的一切都是枉然。
就像我花5元要碗牛肉面,你给我满汉全席,我不会不好意思,但我不会多给你超过5元钱。
11 楼
yxbwzx
2010-12-18
三人行,必有吾师,总能在别人身上学到益处
10 楼
zhang_xzhi_xjtu
2010-12-18
pop1030123 写道
这个类还有什么用处?还可以用来在字符编码间转码吧?
算是一个简单的编码,和base64相似,但是没有base64紧凑。
9 楼
zhang_xzhi_xjtu
2010-12-18
To gdpglc
不好意思,理解错了你说的代码的位置。
主贴已经更新。
这个只是性能提高的一个方面。
还有一个方面是因为append的不同实现。
不好意思,理解错了你说的代码的位置。
主贴已经更新。
这个只是性能提高的一个方面。
public char charAt(int index) { if ((index < 0) || (index >= count)) { throw new StringIndexOutOfBoundsException(index); } return value[index + offset]; }
还有一个方面是因为append的不同实现。
public AbstractStringBuilder append(String str) { if (str == null) str = "null"; int len = str.length(); if (len == 0) return this; int newCount = count + len; if (newCount > value.length) expandCapacity(newCount); str.getChars(0, len, value, count); count = newCount; return this; }
public AbstractStringBuilder append(char c) { int newCount = count + 1; if (newCount > value.length) expandCapacity(newCount); value[count++] = c; return this; }
8 楼
zhang_xzhi_xjtu
2010-12-18
gdpglc 写道
zhang_xzhi_xjtu 写道
gdpglc 写道
"0123456789ABCDEF".charAt(left)
地方还可以优化
char[] chs={'0','1'........'F'}
chs[left]
不过我一定不会这么用。我宁可用Character.forDigit方法,这样的代码可读性太差了。这么在乎性能的理由是什么?你在写系统软件吗?
把乘2写成<<1,唉。我觉得真是精力过剩了..........
这哪能叫重构.... 整个一个反重构
地方还可以优化
char[] chs={'0','1'........'F'}
chs[left]
不过我一定不会这么用。我宁可用Character.forDigit方法,这样的代码可读性太差了。这么在乎性能的理由是什么?你在写系统软件吗?
把乘2写成<<1,唉。我觉得真是精力过剩了..........
这哪能叫重构.... 整个一个反重构
你的改法和我的方法3没有本质区别,但是性能结果不理想。
这个过程也许有一点点过。但是反重构我是不同意的。
软件本身就不是一个简单的事情。看到<<或者>>如果你觉得不舒服我只能说个人的理解不一样。
这个类一看就知道应该是底层协议用的,当然是比较底层的。
1)"0123456789ABCDEF".charAt(left)
2)char[] chs={'0','1'........'F'}
charAt源码:
public char charAt(int index) {
if ((index < 0) || (index >= count)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index + offset];
}
这两行代码的效率是不一样的。因为1)的代码比2)的代码多了一个方法调用、参数传递还有里边判断的过程。
这个的底层协议,导致数据长度比原来增加了一倍,这个方案本身就是粗糙的,然后拼命的提高代码效率...
个人喜好吧
我说了和3本质是一样的,麻烦能不能看看3.
发表评论
-
实践中的重构32_使用标准的IO操作写法。
2012-07-14 18:42 1363看到这样一段代码,功能为读取一个指定文件的内容然后返回。 ... -
实践中的重构31_结果类两种实现的比较
2011-09-13 19:58 1069在查询接口结果类设计 ... -
实践中的重构30_不做油漆匠
2011-08-15 23:42 1241油漆匠的故事是编程文化中的一个著名故事。本地化如下。 小强毕业 ... -
实践中的重构29_不自动的自动化测试
2011-07-31 18:00 1037测试的精髓之一就是自 ... -
实践中的重构28_小心怀疑类库
2011-07-24 10:25 1040一般而言,类库的使用频率较高,场景较多,隐藏的bug就较少。 ... -
实践中的重构27_不要忘了内存空间
2011-06-06 18:31 1167方法在设计中,一般关注的是方法的功能契约,即方法需要什么样的参 ... -
实践中的重构26_奇怪的接口注释
2011-06-06 16:10 1332最近又看到奇怪的注释。 /** * 用户查询服务。 ... -
实践中的重构25_UT也需要持续重构
2011-05-01 11:20 958UT是个好东西,在对代 ... -
实践中的重构24_持续的方法重构
2011-05-01 02:20 1067很少有人可以一遍就写出好的代码。写代码和写文章差不多,大部分人 ... -
实践中的重构23_详尽的注释未必是好注释
2011-03-20 17:37 1506注释一直是软件开发中的一个老大难问题。 代码中一个注释都没有是 ... -
实践中的重构22_不要垃圾
2011-03-20 13:31 1040Java引入了GC当然很好,减轻了程序员手工管理内存的负担,但 ... -
实践中的重构21_给她一个好名字
2011-03-20 13:03 899名字的重要性实在是再怎么强调都不为过的。 为什么名字这么重要呢 ... -
实践中的重构20_一段可笑的异常处理逻辑
2011-03-06 20:32 1669Code review也是一个充满 ... -
实践中的重构19_脱裤子放屁
2011-03-03 23:17 2019每当看到代码中有一个 ... -
实践中的重构18_不对称的美
2011-02-26 22:30 971一般而言,自然界是以 ... -
实践中的重构17_表驱动法
2011-02-22 00:10 840代码以及初始的单元测试见 http://zhang-xzhi- ... -
实践中的重构16_多即是少
2011-01-16 23:44 1504在编写UT的过程中,随处可见重复,硬编码等等使得代码僵化的代码 ... -
实践中的重构15_null的意义和集合类作为方法结果类型
2011-01-12 22:16 631在编程中,估计null应该是一个很常写的词汇了。 实践中,经常 ... -
实践中的重构14_用方法设计保证正确性
2011-01-04 21:40 991一般来说,方法的调用方遵循方法的契约调用某方法来完成某功能。每 ... -
实践中的重构13_利用递归提高代码的可维护性
2010-12-30 01:38 725有这么一段代码,是用来解析国内的地址信息的。 AddressI ...
相关推荐
用于信号的EMD、EEMD、VMD分解_vmd重构_故障诊断emd_故障诊断_故障重构_VMD信号重构_源码.rar.rar
提取MFCC参数,再由MFCC重构幅值谱,利用幅值谱重构语音。
reconfiguration_配电网_配电网络重构_reconfiguration_配电网重构_配电网重构_源码.zip
重构__改善既有代码的设计_高清 绝对清晰
对经验模态分解后的各分量IMF进行重构代码,函数可直接调用。
mutual_information_相空间重构matlab_互信息熵_源码.zip
牛顿拉普逊法就算配电网重构的潮流程序,结构清晰易懂。
PMSM_无传感器FOC_的单分流三相电流重构算法_01299a_cn
mutual_information_相空间重构matlab_互信息熵.zip
资源名:用于信号的EMD、EEMD、VMD分解_vmd重构_故障诊断emd_故障诊断_故障重构_VMD信号重构 资源类型:matlab项目全套源码 源码介绍:用于信号的分解、降噪和重构,实现故障诊断 源码说明: 全部项目源码都是经过...
压缩传感重构算法中的子空间追踪算法,用于信号的重构
可重构密码_博士论文_COBRA1
初中语文语文论文体验中转换拓展后重构__例谈鲸等常识性课文的教学
配电网重构是一个多目标、多时段、多组合、多约束的非线性优化问题。该问题的复杂性,决定了难以用单纯的数学方法得到满意的解。尝试用改进的遗传算法进行配电网络重构,建立评价函数,寻求该评价函数最优解
医学图像三维重构平台,实现了三维重构用VC++实现
31天重构速成_中文版,通过实例来讲解如何运用模式。
reconfiguration_配电网_配电网络重构_reconfiguration_配电网重构_配电网重构.zip
用户重构0113_20160129094530.rp,用户系统重构产品设计,原型和设计
数据信号处理matlab,程序实现压缩感知重构过程,仅供参考。