从java汇编来看java程序的性能优化
来源:互联网 发布:思迅天店 知乎 编辑:程序博客网 时间:2024/05/22 03:48
原文作者为我们指出了一条提高Java 性能的有效方法:使用Java 汇编,但是如何权衡效率与其他软件性能(如可维护性、扩展性)等等,需要读者根据项目需要做出取舍。
这些天一直在用Oolong 学习Java 汇编, 也试图反编译一些java 代码。在这之间突然意识到原来自己过去犯了很多编程的误区,导致代码效率低下。这里列出一些需要注意的地方
1. 尽量避免使用iterator (不是必要的话)
原来自己看C++ 的书,看到STL 里的iterator 的用法,很多书上说这种用法好,如果实现一变,iterator 的代码可以不用修改。我是一个很信书的人,自从那时候开始,我就喜欢上用iterator 了,比如以下代码(第一段)
for(int i=0;i<results.size();i++){
String result = results.get(i);
}
都换成了(第二段)
Iterator<String> iter = results.iterator();
while(iter.hasNext()){
String result = iter.next();
}
最近学习Oolong, 反编译这两段代码,妈妈啊
第一段的Java 汇编是
.line 11
l9: iconst_0
l10: istore 5
l12: iload 5
l14: aload 4
l16: invokevirtual java/util/ArrayList/size ()I
l19: if_icmpge l40
.line 12
l22: aload 4
l24: iload 5
l26: invokevirtual java/util/ArrayList/get (I)Ljava/lang/Object;
l29: checkcast java/lang/String
l32: astore 6
.line 11
l34: iinc 5 1
l37: goto l12
第二段的Java 汇编是
.line 15
l40: aload 4
l42: invokevirtual java/util/ArrayList/iterator ()Ljava/util/Iterator;
l45: astore 5
.line 16
l47: aload 5
l49: invokeinterface java/util/Iterator/hasNext ()Z 1
l54: ifeq l72
.line 17
l57: aload 5
l59: invokeinterface java/util/Iterator/next ()Ljava/lang/Object; 1
l64: checkcast java/lang/String
l67: astore 6
.line 18
l69: goto l47
仔细一看,前一段用的是invokevirtual ,后面那段用的是invokeinterface ,原理上来说invokeinterface 的速度比 invokevirtual 要慢得多,测试两段代码发现,后一段代码耗时比前一段多一个数量级,以后千万不要乱用iterator 了
二如果没有必要,尽量不要使用接口
原来写程序的时候,迷信类型分装,结果不分青红皂白,返回对象清一色的接口
比如一个返回中间结果的方法变成了这样:
public List<String> getList(){
List<String> results = new ArrayList<String>();
return results;
}
处理的方法象这样
public void handle(List<String> contents){
for(int index=0;index<contents.size();index++){
String content = contents.get(index);
}
}
反编译handle 发现
.line 9
l0: iconst_0
l1: istore_2
l2: iload_2
l3: aload_1
l4: invokeinterface java/util/List/size ()I 1
l9: if_icmpge l29
.line 10
l12: aload_1
l13: iload_2
l14: invokeinterface java/util/List/get (I)Ljava/lang/Object; 2
l19: checkcast java/lang/String
l22: astore_3
.line 9
l23: iinc 2 1
l26: goto l2
哎哟,又是invokeinterface ,赶紧的改回来
public void handle(ArrayList<String> contents){
for(int index=0;index<contents.size();index++){
String content = contents.get(index);
}
}
public ArrayList<String> getList(){
ArrayList<String> results = new ArrayList<String>();
return results;
}
这会好了,不在是invokeinterface ,是invokevirtual ,快啊
.line 9
l0: iconst_0
l1: istore_2
l2: iload_2
l3: aload_1
l4: invokevirtual java/util/ArrayList/size ()I
l7: if_icmpge l25
.line 10
l10: aload_1
l11: iload_2
l12: invokevirtual java/util/ArrayList/get (I)Ljava/lang/Object;
l15: checkcast java/lang/String
l18: astore_3
.line 9
l19: iinc 2 1
l22: goto l2
三. 1.5 的新特性, 小心使用
看到1.5 的新特性,好用啊,这个
for(String content:contents){
}
反编译,怎么还是iterator?, 小心, 别乱用哦
l0: aload_1
l1: invokevirtual java/util/ArrayList/iterator ()Ljava/util/Iterator;
l4: astore_2
l5: aload_2
l6: invokeinterface java/util/Iterator/hasNext ()Z 1
l11: ifeq l27
l14: aload_2
l15: invokeinterface java/util/Iterator/next ()Ljava/lang/Object; 1
l20: checkcast java/lang/String
l23: astore_3
.line 10
l24: goto l5
四.1.5 中的String 不再是可怕的性能瓶颈啦
在effective java 里曾经说过,尽量少用String 做连接运算,做字符串连接运算时,StringBuffer 性能更好,可以减少new String 的次数
可是在1.5 里尝试以下代码
String contents = "";
for(int i=0;i<10000;i++)
contents += "Hello";
结果反编译一看,完全不是那么回事
.line 9
l0: ldc ""
l2: astore_1
.line 10
l3: iconst_0
l4: istore_2
l5: iload_2
l6: sipush 10000
l9: if_icmpge l38
.line 11
l12: new java/lang/StringBuilder
l15: dup
l16: invokespecial java/lang/StringBuilder/<init> ()V
l19: aload_1
l20: invokevirtual java/lang/StringBuilder/append (Ljava/lang/String;)Ljava/lang/StringBuilder;
l23: ldc "Hello"
l25: invokevirtual java/lang/StringBuilder/append (Ljava/lang/String;)Ljava/lang/StringBuilder;
l28: invokevirtual java/lang/StringBuilder/toString ()Ljava/lang/String;
l31: astore_1
.line 10
l32: iinc 2 1
l35: goto l5
这里用的就是StringBuffer 的替代品StringBuilder, 当然可能是IBM 的Java 编译器优化,或者是1.5 的编译器优化了(今后在证实),反正目前在ibm JRE 1.5 上编译出来的String 连接代码完全是高效的,至少目前我能放心的用了
- 从Java汇编来看Java程序的性能优化
- 从java汇编来看java程序的性能优化
- 从Java类初始化,来看代码优化
- JAVA程序的性能优化
- Java程序的性能优化
- Java程序的性能优化
- java程序的性能优化
- Java程序性能优化 !
- Java程序性能优化
- Java程序性能优化 !
- Java程序性能优化
- Java程序性能优化
- java程序性能优化
- Java程序性能优化
- Java程序性能优化
- Java程序性能优化
- Java程序性能优化
- Java程序性能优化
- 排序算法之交换排序
- 驱动设备模型---sys文件系统
- Nikto使用方法
- ubuntu下安装新字体并更新字体缓存后,系统显示不正常,花屏,很卡
- 使用ContentResolver操作ContentProvider中的数据
- 从java汇编来看java程序的性能优化
- Classification Probability Models and Conditional Random Fields(2)--HMM
- Hadoop的C++扩展了解(3)
- VC皮肤库SkinSharp 1.0.6.6的使用
- Android中如何做到Service被关闭后又自动启动
- CLLocationManager用法示例 定位
- Zend Framework教程-入门相关
- 最小生成树的kruskal算法
- 给RCP系统添加全局快捷键