编程珠玑第九章--性能之代码调优
2016-09-10 14:06
204 查看
大手术–二分搜索
几个程序的书写
习题
6.0~9,a~z,A~Z看它属于哪一个范围
7.先设计算法计算每一个输入单元,int 或者是char;
对于int,方法一:number&(1<
运行结果
8.利用哨兵元素寻找最大值
*
11.因为只需要角度为5度的整数倍时才需要计算。360/5=72;因为0与360是等价的,所以只需要取其一即可。所以只要利用表格记录角度为0,5,10,15,…….,355对应的三角函数值即可
12.人们在调优程序时有时会从数学的角度而不是代码的角度看问题。
几个程序的书写
package chapter9; public class BinarySort { public static int binarySort0(int x[],int number){ int l=0,r=x.length-1; int m=0; while(true){ if(l>r){ return -1; } m=(l+r)/2; if(x[m]>number){ r=m-1; } if(x[m]==number){ return m; } if(x[m]<number){ l=m+1; } } } //我们假定x[-1]<t;x =>t只是假想并不实际进行访问这两个元素;然后在循环进入条件l+1!=m,并且根据m=(l+r)/2;通过对x[m]与number的比较,不断更新l或r,使得x[l]<t,x[r]>=t始终成立,甚至最终l+1=m跳出循环时仍然成立,此时看一下r是否为所求下标; public static int binarySort1(int x[],int number){ int l=-1,r=x.length; while(l+1!=r){ int m=(l+r)/2; if(x[m]<number){ l=m; } else { r=m; } } if(r>=x.length||x[r]!=number)//r>=x.length保证不会访问x ; return -1; else { return r; } } //假设n=1000;程序里我们不使用l,r表示数组的左右边界;而是使用l+i来表示右边界, //所以就要使得l+i=r,并且我们要是i是2的正整数次 ; public static int binarySort2_a(int x[],int number){ int i=512; int l=-1; if(x[511]<number){ l=1000-i;//确保l...l+incremnt要么为-1...511,要么是488...512; } int next_i; while(i!=1){ //循环不变式:x[l]<number&&x[l+i]>=number&&i=2^j; next_i=i/2; if(x[l+next_i]<number){ l+=next_i; i=next_i; } else { i=next_i; } } // assert(i==1&&x[l]<number&&x[l+i]>=number); int p=l+1; if(p>1000||x[p]!=number){ return -1; } return p; } public static int binarySort2_b(int x[],int dad5 number){ int i=512; int l=-1; if(x[511]<number){ l=1000-i;//确保l...l+incremnt要么为-1...511,要么是488...512; } while(i!=1){ //循环不变式:x[l]<number&&x[l+i]>=number&&i=2^j; i=i/2; if(x[l+i]<number){ l+=i; } } // assert(i==1&&x[l]<number&&x[l+i]>=number); int p=l+1; if(p>1000||x[p]!=number){ return -1; } return p; } public static int binarySort3(int x[],int number){ int i=512; int l=-1; if(x[511]<number){ l=1000-i;//确保l...l+incremnt要么为-1...511,要么是488...512; } if(x[l+256]<number)l+=256; if(x[l+128]<number)l+=128; if(x[l+64]<number)l+=64; if(x[l+32]<number)l+=32; if(x[l+16]<number)l+=16; if(x[l+8]<number)l+=8; if(x[l+4]<number)l+=4; if(x[l+2]<number)l+=2; if(x[l+1]<number)l+=1; // assert(i==1&&x[l]<number&&x[l+i]>=number); int p=l+1; if(p>1000||x[p]!=number){ return -1; } return p; } }
习题
6.0~9,a~z,A~Z看它属于哪一个范围
7.先设计算法计算每一个输入单元,int 或者是char;
对于int,方法一:number&(1<
package chapter9; import java.util.HashMap; public class t7 { //因为Java里int为32位,并且只有有符号数只能访问到31位 //方法一:number&(1<<i);找到对应的每一位的值, //当然这个方法对于每个int都要运行31次 public static int countInt0( int number){ int temp=0; int count=0; for(int i=0;i<31;i++){ temp=number&(1<<i); // System.out.print(temp+" "); if(temp!=0){//事实上,temp应该等于1<<i;才会进行count++ count++; } } // System.out.println(); return count; } //方法二:使用number&=(number-1),对number中是1的位进行迭代,直到b==0,跳出循环 //可以看出方法二运行的次数就是number中位为1的个数,比方法一肯定是快的; public static int countInt1(int number){ int count=0; while(number>0){ number&=(number-1); // System.out.print(number+" "); count++; } // System.out.println(); return count; } //对于字符位为1的个数,只需将字符转换成int就好,然后就利用countInt1可以直接来算 public static int countChar(char c){ int re=Integer.valueOf(c); // System.out.println(re); return countInt1(re); } //优化是用一个HashMap进行保存各个数字及其位为1的个数,键位数字+""或者字符+"",值为个数; //对于每一个数先看hashmap里是否包含,若是包含就直接取值,若是不包含则使用上述的方法二countInt1进行计算并保存 static HashMap<String, Integer> hashMap=new HashMap<String, Integer>(); //当然另一种优化就是看看对所有输入单元进行统计,看看每一个单元出现的次数,然后存储下次数,最后对于不同的单元计算其1出现的个数并乘以个数,最后相加 //其实和上面的优化的效率差不多 public static long countExample(){ int arr[]={31,31,30,30}; char cArr[]="aabb".toCharArray(); long count=0; int temp; for(int i=0;i<arr.length;i++){ if(!hashMap.containsKey(arr[i]+"")){ temp=countInt1(arr[i]); count+=temp; hashMap.put(arr[i]+"", temp); System.out.println("store "+arr[i]); } else { count+=hashMap.get(arr[i]+""); System.out.println("from the store "); } } for(int i=0;i<cArr.length;i++){ if(!hashMap.containsKey(cArr[i]+"")){ temp=countChar(cArr[i]); count+=temp; hashMap.put(cArr[i]+"", temp); System.out.println("store "+cArr[i]); } else { count+=hashMap.get(cArr[i]+""); System.out.println("from the store "); } } return count; } public static void main(String args[]){ // System.out.println(Integer.SIZE); // System.out.println(Integer.MAX_VALUE); // System.out.println(Integer.MIN_VALUE); // System.out.println(Character.SIZE);//0000-FFFF 16位 // System.out.println(Character.MIN_VALUE+" "); // System.out.println("方法一"); // System.out.println(countInt0(255)); // System.out.println(countInt0(254)); // System.out.println(countInt0(253)); // System.out.println(countInt0(1023)); // System.out.println(countInt0(1022)); // System.out.println(countInt0(1021)); // System.out.println("\n\n"); // System.out.println("方法二"); // System.out.println(countInt1(255)); // System.out.println(countInt1(254)); // System.out.println(countInt1(253)); // System.out.println(countInt1(1023)); // System.out.println(countInt1(1022)); // System.out.println(countInt1(1021)); // System.out.println("\n\n"); // System.out.println("count char"); // System.out.println(countChar('a')); System.out.println(countExample()); } }
运行结果
store 31 from the store store 30 from the store store a from the store store b from the store 30
8.利用哨兵元素寻找最大值
*
package chapter9; public class t8 { public static int findMax(int arr[]){ // arr[arr.length-1]用来作为哨兵元素 int i=0; int n=arr.length-1; int max=0; while(i<n){ max=arr[i]; arr =max; i++; while(arr[i]<max){ i++;//直到找到比现在max大或等于的;或者最终i==n,找到哨兵,跳出循环 } } return max; } public static void main(String args[]){ System.out.println(findMax(new int[]{5,4,3,3,1})); } }
11.因为只需要角度为5度的整数倍时才需要计算。360/5=72;因为0与360是等价的,所以只需要取其一即可。所以只要利用表格记录角度为0,5,10,15,…….,355对应的三角函数值即可
12.人们在调优程序时有时会从数学的角度而不是代码的角度看问题。
package chapter9; public class t12 { public static int compute(int a[],int x){ int y=a[0]; int n=a.length-1; int temp=1; for(int i=1;i<=n;i++){ temp=x*temp; y+=a[i]*temp; // System.out.print(y+" "); } // System.out.println(); return y; } public static int compute1(int a[],int x){ int n=a.length-1; int y=a ; for(int i=n-1;i>=0;i--){ y=x*y+a[i];//利用n次乘法,按需要与x的乘积次数将a数组里的元素一一放入,进行乘积 } return y; } public static void main(String args[]){ System.out.println(compute(new int[]{1,1,1,1,1}, 2)); System.out.println(compute1(new int[]{1,1,1,1,1}, 2)); } }
相关文章推荐
- 编程珠玑 - 代码调优法则 - 基础篇
- ADO.Net炸弹代码性能调优
- Java代码性能调优
- NodeJS的代码调试和性能调优
- NodeJS的代码调试和性能调优
- 如何用vc6自带功能进行c/c++代码性能调优
- Java性能调优之代码调优(一)
- 74. 性能调优的道路上遍布脏代码炸弹
- 【技术文档】《编程珠玑》Jon Bentley·第9章 代码调优
- JVM 性能调优实战之:使用阿里开源工具 TProfiler 在海量业务代码中精确定位性能代码
- 【编程珠玑】第九章 代码调优
- MapReduce的性能调优-代码调优
- 性能调优代码
- [大牛翻译系列]Hadoop(15)MapReduce 性能调优:优化MapReduce的用户JAVA代码
- 系统性能调优(5)----Java循环与字符串代码优化
- 第九章 代码调优
- java 性能调优之-快速定位引起内存泄露的代码
- 代码优化 性能调优
- 《编程珠玑》阅读小记(7) — 代码调优与节省空间
- [置顶] JVM 性能调优实战之:使用阿里开源工具 TProfiler 在海量业务代码中精确定位性能代码