使用javap分析你的程序性能(以字符串拼接为例)

javap是JDK自带的反汇编器,可以查看java编译器为我们生成的字节码。通过它,我们可以对照源代码和字节码,从而了解很多编译器内部的工作。

语法:
  javap [ 命令选项 ] class. . .
  javap 命令用于解析类文件。其输出取决于所用的选项。若没有使用选项,javap 将输出传递给它的类的 public 域及方法。javap 将其输出到标准输出设备上。
命令选项
  -help 输出 javap 的帮助信息。
  -l 输出行及局部变量表。
  -b 确保与 JDK 1.1 javap 的向后兼容性。
  -public 只显示 public 类及成员。
  -protected 只显示 protected 和 public 类及成员。
  -package 只显示包、protected 和 public 类及成员。这是缺省设置。
  -private 显示所有类和成员。
  -J[flag] 直接将 flag 传给运行时系统。
  -s 输出内部类型签名。
  -c 输出类中各方法的未解析的代码,即构成 Java 字节码的指令。
  -verbose 输出堆栈大小、各方法的 locals 及 args 数,以及class文件的编译版本
  -classpath[路径] 指定 javap 用来查找类的路径。如果设置了该选项,则它将覆盖缺省值或 CLASSPATH 环境变量。目录用冒号分隔。
   - bootclasspath[路径] 指定加载自举类所用的路径。缺省情况下,自举类是实现核心 Java 平台的类,位于 jrelib
  t.jar 和 jrelibi18n.jar 中。
  -extdirs[dirs] 覆盖搜索安装方式扩展的位置。扩展的缺省位置是 jrelibext

1、创建一个Java文件Concatenation.java :

 1 public class Concatenation {
 2     public static void main(String[] args) {
 3     }
 4     
 5     /**
 6      * Using String mode
 7      * @param fields
 8      * @return
 9      */
10     public String implicit(String[] fields) {
11         String result = "";
12         for (int i = 0; i < fields.length; i++) {
13             result += fields[i];
14         }
15         return result;
16     }
17     
18     /**
19      * Using StringBuilder mode
20      * @param fields
21      * @return
22      */
23     public String explicit(String[] fields) {
24         StringBuilder result = new StringBuilder();
25         for (int i = 0; i < fields.length; i++) {
26             result.append(fields[i]);
27         }
28         return result.toString();
29     }
30 }

2、将文件拷贝至目录D盘下(你也不一定非要拷贝这里,任意位置)

3、执行编译命令,先生成class文件,生成结束后D盘将会多出一个Concatenation.class的文件

  D:\>javac Concatenation.java

4、执行javap命令,执行完命令后会在命令框内显示很多行字符串,据说懂汇编的能看懂,不过咱也可以认识一些关键字,大概知道啥意识

      D:\>javap -c Concatenation

输出内容如下:


implicit方法:
从第8行到第35行构成了一个循环体(根据goto语句认出来的),然后可以看到第11行,是在循环体内哦,每次都会New一次StringBuilder对象...

explicit方法:
再看看这个方法,不仅循环部分的代码更简短、更简单、而且它至生成了一个StringBuilder对象

tip:StringBuilder与StringBuffer的区别
1. 在执行速度方面的比较:StringBuilder > StringBuffer
2. StringBuffer与StringBuilder,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,不像String一样创建一些对象进行操作,所以速度就快了。
3. StringBuilder:线程非安全的   StringBuffer:线程安全的 当我们在字符串缓冲去被多个线程使用是,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的,就是速度的原因。
对于三者使用的总结:
1.如果要操作少量的数据用 = String       
2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder       
3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer

本文引自《Java 编程思想(第四版)》的第284页,有兴趣的可以看看:)

posted @ 2012-11-22 16:42  易木  阅读(699)  评论(0编辑  收藏  举报