`

循环的优化

    博客分类:
  • java
阅读更多
 循环的优化 
 ---------------------------------------
 1,数字比较尽量和0比较
 注释:计算机喜欢0和1
 //foo
 for(int i=0;i<Integer.MAX_VALUE;i++){
     //慢
 }
 //优化
 for(int i=Integer.MAX_VALUE;i>0;i--){
     //快
 }

 2,尽量把异常捕获写在外面
 //foo
 for(int i=180000;i>=0;i--){
 try{
 //慢
 }catch{
 }
 }

 //优化
 try{
 for(int i=180000;i>=0;i--){
 //快

 }
 }catch{
 }
 ---------------------------------------
 3,尽量不要在循环内有多余的方法调用
 //注释:除了方法调用本身耗费资源外,其方法内代码体的多次执行根据实际情况影响性能和内存,调用一次能解决问题就别调用两次
 for(int i=0;i>=IntMethod();i--){

 }
 //优化
 int len = IntMethod():
 for(int i=0;i>=len;i--){

 }


 ---------------------------------------
 4, 在循环中最好不要拼接字符串一
 注释:String是不变类,对其更改都会重新创建字符串,从而导致内存和速

度的问题,
 另外StringBuilder是sun为解决字符串操作效率低下而创建
地(StringBuffer早),
 有字符buffer,解决字符的增删改都是相当快滴
 //foo
 String str = "";
 for (int i = 0; i >= 18000; i--) {
     // 慢 占用内存大
     str += "慢 占用内存大";
 }
 //优化
 StringBuilder yourString = new StringBuilder();
 for (int i = 0; i >= 18000; i--) {
     // 快 占用内存小
     yourString.append("快 占用内存小");
 }
 ---------------------------------------
 5, 在循环中最好不要拼接字符串之二
 注释:看编译后代码,一目了然
 //foo
 StringBuilder yourString = new StringBuilder();
 for (Integer i = 0; i >= 18000; i--) {
     yourString.append("" + i);
 }
 // 优化
 for (Integer i = 0; i >= 18000; i--) {
     yourString.append(i.toString());
 }
 //编译后代码         注:经过处理
 /*
 //foo
 StringBuilder yourString = new StringBuilder();
 for (Integer i = Integer.valueOf(0); i.intValue() >= 18000; i = 

Integer.valueOf(i.intValue() - 1))
     yourString.append((new StringBuilder()).append(i).toString());
 // 优化
 for (Integer i = Integer.valueOf(0); i.intValue() >= 18000; i = 

Integer.valueOf(i.intValue() - 1))
     yourString.append(i.toString());
 */
分享到:
评论
43 楼 yf42 2009-09-25  
第一条的理解有问题,貌似不是因为比较的原因(想不明白跟0比为什么会快),是cpu少一次计算的问题(汇编忘的差不多了,不过好像是循环用+是3条指令,-是2条指令)
42 楼 zhaomingzm_23 2009-09-23  
oxromantic 写道
sunflowers 写道
jieping310 写道

var.equals("123");这个有什么问题?

var是个变量,变量就有可能为null,而"123"是个常量,永远都不可能给为null

所以字符串比较时,标准的写法应该是"123".equals(var);


var.equals("123")才是标准的写法,"123".equals(var)会吃掉空指针的异常情况

对于任何一个稳健的系统而言,更期待的是抛出异常而不是吃掉异常

"123".equals(var)受早期精简代码的影响,现在想来不可取

个人理解:优秀的代码往往是冗余的

ps:
var.equals("123")这种写法完全可以由jvm优化,好像新的jdk已经包含相关的feature



其实这个var.equals("123")的问题要看上下文
如果人家在var.equals("123")之前已经 if(var == null) return;了呢?
还有就是我们是中国人主语靠前的程序容易阅读。我们写程序不是给机器看的,是给人看的。看过《实现模式》的朋友应该知道程序代码交流的重要性.
PS:在Groovy中可以这样避免这个问题 var?.equal("123"),带上这个问号,编译器会处理null value invoke.
以上个人见解,呵呵
41 楼 oxromantic 2008-12-24  
sunflowers 写道
jieping310 写道

var.equals("123");这个有什么问题?

var是个变量,变量就有可能为null,而"123"是个常量,永远都不可能给为null

所以字符串比较时,标准的写法应该是"123".equals(var);


var.equals("123")才是标准的写法,"123".equals(var)会吃掉空指针的异常情况

对于任何一个稳健的系统而言,更期待的是抛出异常而不是吃掉异常

"123".equals(var)受早期精简代码的影响,现在想来不可取

个人理解:优秀的代码往往是冗余的

ps:
var.equals("123")这种写法完全可以由jvm优化,好像新的jdk已经包含相关的feature
40 楼 sunflowers 2008-11-05  
zgd 写道

拼接字符串的就不用说了。第一条,我不信编译器或者JVM没有帮你优化第二条,两个代码的行为不一样啊



你不信:是你的主观愿望,要真正测试才可以,第一条我已经说过,意义不大,

对于参加异常讨论的朋友,我有句话,非常严重的告诉你

【编译器编译的时候要对语句进行语法分析的】,所以你在编译我的事例的时候,也要分析我的语法,我前面有个词语【尽量】,不知道你们分析到了没有,如果你们没有分析到,所以,你们会报异常的,由此,我来写这个帖子来捕获你们的异常来了,O(∩_∩)O哈哈~,开个玩笑,do,do do 
39 楼 iwalyx 2008-11-04  
受教了,不过个人感觉,除了研究所以外,做的东西都是给客户或客人的.
38 楼 zgd 2008-11-04  
拼接字符串的就不用说了。

第一条,我不信编译器或者JVM没有帮你优化
第二条,两个代码的行为不一样啊
37 楼 delphixp 2008-11-04  
taupo 写道
try{  
for(int i=180000;i>=0;i--){  
//快  
 
}  
}catch{  



按楼主这样做有个很大的问题。。。。如果i=100的时候抛了异常,100以后的就不能继续循环了。。。



那是当然的,楼主所说的是,当有异常时,循环就中断的话,最好将 try{}catch() 放在循环的外面。但,如果出现异常时,仍不能中断循环时,则 try..catch 就不能放在外面了。。。
36 楼 taupo 2008-11-04  
try{  
for(int i=180000;i>=0;i--){  
//快  
 
}  
}catch{  



按楼主这样做有个很大的问题。。。。如果i=100的时候抛了异常,100以后的就不能继续循环了。。。

35 楼 sunflowers 2008-11-04  
freish 写道

即使是3那样的代码,java编译器应该做了优化了吧,如果这样的代码都不能优化,那编译器也够失败的了



34 楼 freish 2008-11-04  
即使是3那样的代码,java编译器应该做了优化了吧,如果这样的代码都不能优化,那编译器也够失败的了
33 楼 guooscar 2008-11-01  
传递的参数是null,是否意味着有错误呢
呵呵 让我想起了 鸵鸟算法
32 楼 sunflowers 2008-10-31  
还有一个小小的好处是,此时的var 可以是任何对象

即使是null

呵呵
31 楼 sunflowers 2008-10-31  
jieping310 写道


我只要先做个判断就可以啊
var != null &amp;&amp; var.equals("123")这样跟 "123".equals(var);性能上有很大区别么?


两者的性能差别不是太大,

你的判断完全可以省略,

变成简洁、高效、易读的 "123".equals(var)【相比较你的判断】;

这种问题自己在平时可以注意一下,稍微思考,应该不是问题


30 楼 jieping310 2008-10-31  
sunflowers 写道
jieping310 写道

var.equals("123");这个有什么问题?

var是个变量,变量就有可能为null,而"123"是个常量,永远都不可能给为null

所以字符串比较时,标准的写法应该是"123".equals(var);


我只要先做个判断就可以啊
var != null && var.equals("123")这样跟 "123".equals(var);性能上有很大区别么?
29 楼 WhisperXD 2008-10-31  
sunflowers 写道
jieping310 写道

var.equals("123");这个有什么问题?

var是个变量,变量就有可能为null,而"123"是个常量,永远都不可能给为null

所以字符串比较时,标准的写法应该是"123".equals(var);


这个学到了:)。。
28 楼 sunflowers 2008-10-31  
jieping310 写道

var.equals("123");这个有什么问题?

var是个变量,变量就有可能为null,而"123"是个常量,永远都不可能给为null

所以字符串比较时,标准的写法应该是"123".equals(var);
27 楼 jieping310 2008-10-31  
sunflowers 写道
lyy5271 写道

我觉得这些东西可以扩展知识面,但用处不大。举个例子,访问二维数组的时候按行优先比按列优先效率要高,原因是所谓的局部性原理,可以充分利用计算机的高速缓存,可是这些东西对做java的企业应用有什么用处呢?反正我觉得没有什么用处。


不敢苟同!如果仅仅是类似我文章类似1的优化,你的观点是正确的,

但是对于类似很多以下几个的优化,你的观点确实应该值得每一个认为无所为的程序员深思。

我们是写程序的,写出优秀的代码应该是我们共同的目标,不应当因系统的规模大小和难易程

度而改变我们的追求。当你看别人程序的时候,一个有很多年java开发经验的时候,你也许会

发现类似这样的拙劣:var.equals("123");,也许这样写是小事,可是我觉得这样写对于初学者

是可以原谅的……。回过头来看345,如果是企业应用,你的代码也许正在严重影响性能

一句话总结:无论你写的是什么样系统,都应该把你最好的代码写进去。


var.equals("123");这个有什么问题?
26 楼 leirdal 2008-10-30  
BenoWay 写道
for(int i=0;i<Integer.MAX_VALUE;i++){  
     //慢  
}  
//优化  
for(int i=Integer.MAX_VALUE;i>=0;i--){  
     //快  
}  
这个循环次数一样吗?

下面多了一次循环。
25 楼 leirdal 2008-10-30  
public static void main(String[] args) {
for (int i = 0; i < 20; i++) {
compare();
}
}
static void compare(){
final int MAX = 10000000;
long start = System.currentTimeMillis();
for (int i = 0; i < MAX; i++) {
}
System.out.println("end == " + (System.currentTimeMillis() - start));
long start1 = System.currentTimeMillis();
for (int k = MAX; k > 0; k--) {
}
System.out.println("end == " + (System.currentTimeMillis() - start1));
System.out.println("====================================");
}

结果:
end == 47
end == 31
====================================
end == 16
end == 31
====================================
end == 16
end == 31
====================================
end == 15
end == 32
====================================
end == 15
end == 32
====================================
end == 15
end == 31
====================================
end == 16
end == 31
====================================
end == 16
end == 31
====================================
end == 16
end == 31
====================================
end == 31
end == 16
====================================
end == 31
end == 16
====================================
end == 31
end == 16
====================================
end == 31
end == 15
====================================
end == 32
end == 15
====================================
end == 32
end == 31
====================================
end == 15
end == 32
====================================
end == 15
end == 32
====================================
end == 15
end == 31
====================================
end == 16
end == 31
====================================
end == 16
end == 31
====================================
24 楼 BenoWay 2008-10-30  
for(int i=0;i<Integer.MAX_VALUE;i++){  
     //慢  
}  
//优化  
for(int i=Integer.MAX_VALUE;i>=0;i--){  
     //快  
}  
这个循环次数一样吗?

相关推荐

Global site tag (gtag.js) - Google Analytics