java修改前后差异_java代码优化前后性能对比测试

importjava.util.ArrayList;

importjava.util.Date;

importjava.util.HashMap;

importjava.util.Iterator;

importjava.util.Map;

importjava.util.Set;

importjava.util.StringTokenizer;

publicclassTest {

publicstaticvoidmain(String argv[]) {

/*

* 避免在循环条件中使用复杂表达式

* @author yifangyou

* @since 2011-08-16 09:35:00

*

*/

//      test0();

/*

* 如果只是查找单个字符的话,用charAt()代替startsWith()

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

//      test1();

/*

* 能够使用移位的乘除,最好用移位

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

//       test2();

/*

* 只有一个字符的字符串拼接,用''代替""

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

//       test3();

/**

* try catch最好不要放在循环里

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

//       test4();

/**

* switch的实现 map比较稳定,if最慢,switch在数量少于10个时最快,随着数量增加下降厉害

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

//      test5();

/*

* 对于常量字符串,用'String' 代替 'StringBuffer' ,节省空间,节省时间

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

//      test6();

/*

* 用'StringTokenizer' 代替 'indexOf()' 和'substring()'

* 字符串的分析在很多应用中都是常见的。使用indexOf

* ()和substring()来分析字符串容易导致StringIndexOutOfBoundsException。

* 而使用StringTokenizer类来分析字符串则会容易一些,效率也会低一些。

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

//       test7();

/*

* 不要在循环体中实例化变量 在循环体中实例化临时变量将会增加内存消耗

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

//       test8();

/*

* 确定 StringBuffer的容量

* StringBuffer的构造器会创建一个默认大小(通常是16)的字符数组。在使用中,如果超出这个大小

* ,就会重新分配内存,创建一个更大的数组,并将原先的数组复制过来,再丢弃旧的数组。在大多数情况下,你可以在创建

* StringBuffer的时候指定大小,这样就避免了在容量不够的时候自动增长,以提高性能。

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

//       test9();

/*

* 尽可能的使用栈变量

*

* 如果一个变量需要经常访问,那么你就需要考虑这个变量的作用域了。static?

* local?还是实例变量?访问静态变量和实例变量将会比访问局部变量多耗费2-3个时钟周期。

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

//      test10();

/**

* 复制数组最好用System.arraycopy 逐个复制,最慢;批量复制,最快

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

//      copyArray();

/*

* 复制ArrayList数组最好用addAll addAll,最快;clone,次之,逐个最慢

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

//      copyArrayList();

/*

* 复制Map最好用逐个复制最快,putAll最简单

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

copyMap();

}

intlocalN =0;

staticintstaticN =0;

/*

* 避免在循环条件中使用复杂表达式

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

publicstaticvoidtest0() {

ArrayList a =newArrayList();

for(inti =0; i <10000000; i++) {

a.add(i);

}

longstartTime;

// 循环条件中使用复杂表达式

startTime =newDate().getTime();

for(inti =0; i 

intj = a.get(i);

}

System.out.println(newDate().getTime() - startTime);

// 循环条件中不使用复杂表达式

startTime =newDate().getTime();

for(inti =0, maxlen = a.size(); i 

intj = a.get(i);

}

System.out.println(newDate().getTime() - startTime);

}

/*

* 如果只是查找单个字符的话,用charAt()代替startsWith()

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

publicstaticvoidtest1() {

String s ="sdfsdfsdfsdfdssssssssssssssssssssssssssssdfffffffffffffffa";

longstartTime;

// startsWith

startTime =newDate().getTime();

for(inti =0; i <10000000; i++) {

if(s.startsWith("a")) {

}

}

System.out.println(newDate().getTime() - startTime);

// charAt

startTime =newDate().getTime();

for(inti =0; i <10000000; i++) {

if(s.charAt(0) =='a') {

}

}

System.out.println(newDate().getTime() - startTime);

// charAt

startTime =newDate().getTime();

for(inti =0; i <10000000; i++) {

if("ab".equals("abcdssdds".substring(0,2))) {

}

}

System.out.println(newDate().getTime() - startTime);

}

/*

* 能够使用移位的乘除,最好用移位

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

publicstaticvoidtest2() {

longstartTime;

inta;

//

startTime =newDate().getTime();

for(inti =0; i <10000000; i++) {

a =333333333/8;

}

System.out.println(newDate().getTime() - startTime);

// charAt

startTime =newDate().getTime();

for(inti =0; i <10000000; i++) {

a =333333333>>3;

}

System.out.println(newDate().getTime() - startTime);

}

/*

* 只有一个字符的字符串拼接,用''代替""

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

publicstaticvoidtest3() {

longstartTime;

startTime =newDate().getTime();

String s ="123";

for(inti =0; i <10000000; i++) {

String a = s +"d";

}

System.out.println(newDate().getTime() - startTime);

// charAt

startTime =newDate().getTime();

for(inti =0; i <10000000; i++) {

String a = s +'d';

}

System.out.println(newDate().getTime() - startTime);

}

/**

* try catch最好不要放在循环里

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

publicstaticvoidtest4() {

longstartTime;

startTime =newDate().getTime();

for(inti =0; i <10000000; i++) {

try{

inta = Integer.parseInt("1");

}catch(Exception e) {

}

}

System.out.println(newDate().getTime() - startTime);

startTime =newDate().getTime();

try{

for(inti =0; i <10000000; i++) {

inta = Integer.parseInt("1");

}

}catch(Exception e) {

}

System.out.println(newDate().getTime() - startTime);

}

/**

* switch的实现 map比较稳定,if最慢,switch在数量少于10个时最快,随着数量增加下降厉害,在switch最好把出现次数最多的判断放在最前面

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

publicstaticvoidtest5() {

HashMap types =newHashMap() {

{

inti =0;

this.put("a", i++);

this.put("b", i++);

this.put("c", i++);

this.put("d", i++);

this.put("e", i++);

}

};

String a ="e";

intb =0;

longstartTime;

startTime =newDate().getTime();

for(inti =0; i <10000000; i++) {

if("a".equals(a)) {

b =0;

}elseif("b".equals(a)) {

b =1;

}elseif("c".equals(a)) {

b =2;

}elseif("d".equals(a)) {

b =3;

}elseif("e".equals(a)) {

b =4;

}

}

System.out.println(newDate().getTime() - startTime);

startTime =newDate().getTime();

for(inti =0; i <10000000; i++) {

b = types.get(a);

}

System.out.println(newDate().getTime() - startTime);

intc =14;//改为0的话则最快

startTime =newDate().getTime();

for(inti =0; i <10000000; i++) {

switch(c) {

case0:

break;

case1:

break;

case2:

break;

case3:

break;

case4:

break;

case5:

break;

case6:

break;

case7:

break;

case8:

break;

case9:

break;

case10:

break;

case11:

break;

case12:

break;

case13:

break;

case14:

break;

default:

break;

}

}

System.out.println(newDate().getTime() - startTime);

}

/*

* 对于常量字符串,用'String' 代替 'StringBuffer' ,节省空间,节省一半时间

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

publicstaticvoidtest6() {

StringBuffer s =newStringBuffer("Hello");

intmaxlen=1000000;

longstartTime;

startTime =newDate().getTime();

for(inti =0; i 

String t =newString("Hello ") +"World!";

}

System.out.println(newDate().getTime() - startTime);

startTime =newDate().getTime();

for(inti =0; i 

StringBuffer t =newStringBuffer("Hello ").append("World!");

}

System.out.println(newDate().getTime() - startTime);

}

/*

* 用'StringTokenizer' 代替 'indexOf()' 和'substring()'

* 字符串的分析在很多应用中都是常见的。使用indexOf

* ()和substring()来分析字符串容易导致StringIndexOutOfBoundsException。

* 而使用StringTokenizer类来分析字符串则会容易一些,效率也会低一些。

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

publicstaticvoidtest7() {

String domain ="www.a.com.";

longstartTime;

startTime =newDate().getTime();

for(inti =0; i <100000; i++) {

intindex =0;

while((index = domain.indexOf(".", index +1)) != -1) {

domain.substring(index +1, domain.length());

// System.out.println(domain.substring(index+1,

// domain.length()));

}

}

System.out.println(newDate().getTime() - startTime);

startTime =newDate().getTime();

for(inti =0; i <100000; i++) {

StringTokenizer st =newStringTokenizer(domain,".");

while(st.hasMoreTokens()) {

st.nextToken();

// System.out.println(st.nextToken());

}

}

System.out.println(newDate().getTime() - startTime);

}

/*

* 不要在循环体中实例化变量 在循环体中实例化临时变量将会增加内存消耗

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

publicstaticvoidtest8() {

ArrayList a =newArrayList();

intmaxlen =10000000;

for(inti =0; i 

a.add(i);

}

longstartTime;

startTime =newDate().getTime();

for(inti =0; i 

Object o =newObject();

o = a.get(i);

}

System.out.println(newDate().getTime() - startTime);

Object o =newObject();

startTime =newDate().getTime();

for(inti =0; i 

o = a.get(i);

}

System.out.println(newDate().getTime() - startTime);

}

/*

* 确定 StringBuffer的容量

* StringBuffer的构造器会创建一个默认大小(通常是16)的字符数组。在使用中,如果超出这个大小,就会重新分配内存

* ,创建一个更大的数组,并将原先的数组复制过来,再丢弃旧的数组。在大多数情况下,你可以在创建

* StringBuffer的时候指定大小,这样就避免了在容量不够的时候自动增长,以提高性能。

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

publicstaticvoidtest9() {

intmaxlen =1000000;

longstartTime;

startTime =newDate().getTime();

for(inti =0; i 

StringBuffer buffer =newStringBuffer();// violation

buffer.append("hellosdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");

}

System.out.println(newDate().getTime() - startTime);

startTime =newDate().getTime();

for(inti =0; i 

StringBuffer buffer =newStringBuffer(128);// violation

buffer.append("hellosdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");

}

System.out.println(newDate().getTime() - startTime);

}

/*

* 尽可能的使用栈变量 如果一个变量需要经常访问,那么你就需要考虑这个变量的作用域了。static?

* local?还是实例变量?访问静态变量和实例变量将会比访问局部变量多耗费2-3个时钟周期。

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

publicstaticvoidtest10() {

intmaxlen =100000000;

longstartTime;

intn =0;

Test test =newTest();

// 局部变量

startTime =newDate().getTime();

for(inti =0; i 

n = i;

}

System.out.println(newDate().getTime() - startTime);

// 类变量

startTime =newDate().getTime();

for(inti =0; i 

test.localN = i;

}

System.out.println(newDate().getTime() - startTime);

// 静态变量

startTime =newDate().getTime();

for(inti =0; i 

Test.staticN = i;

}

System.out.println(newDate().getTime() - startTime);

}

//

//  /*1.尽量使用final修饰符。

//带有final修饰符的类是不可派生的。在JAVA核心API中,有许多应用final的例子,例如java.lang.String。为String类指定final防止了使用者覆盖length()方法。另外,如果一个类是final的,则该类所有方法都是final的。java编译器会寻找机会内联(inline)所有的final方法(这和具体的编译器实现有关)。此举能够使性能平均提高50%。

//   */

//  public static void test11() {

//      int maxlen = 10000000;

//      long startTime;

//      int n = 0;

//

//      // 普通类

//      startTime = new Date().getTime();

//      A a = new A();

//      for (int i = 0; i 

//          a.inc();

//      }

//      System.out.println(new Date().getTime() - startTime);

//

//      // final类

//      startTime = new Date().getTime();

//      FinalA finalA = new FinalA();

//      for (int i = 0; i 

//          finalA.inc();

//      }

//      System.out.println(new Date().getTime() - startTime);

//  }

/**

* 复制数组最好用System.arraycopy 逐个复制,最慢;批量复制,最快

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

staticvoidcopyArray() {

int[] array1 =newint[10000000];

int[] array2 =newint[10000000];

for(inti =0, maxlen = array1.length; i 

array1[i] = i;

}

longstartTime;

// 逐个复制,最慢

startTime =newDate().getTime();

for(inti =0, maxlen = array2.length; i 

array2[i] = array1[i];// Violation

}

System.out.println(newDate().getTime() - startTime);

// 批量复制,最快

startTime =newDate().getTime();

System.arraycopy(array1,0, array2,0,10000);

System.out.println(newDate().getTime() - startTime);

}

/*

* 复制ArrayList数组最好用addAll addAll,最快;clone,次之,逐个最慢

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

staticvoidcopyArrayList() {

intmaxlen =1000000;

ArrayList array1 =newArrayList();

ArrayList array2 =newArrayList();

ArrayList array3 =newArrayList();

ArrayList array4;

for(inti =0; i 

array1.add(i);

}

longstartTime;

// 逐个复制,最慢

startTime =newDate().getTime();

for(inti =0; i 

array2.add(array1.get(i));// Violation

}

System.out.println(newDate().getTime() - startTime);

// 批量复制,最快

startTime =newDate().getTime();

array3.addAll(array1);

System.out.println(newDate().getTime() - startTime);

// 克隆,次快

startTime =newDate().getTime();

array4 = (ArrayList) array1.clone();

System.out.println(newDate().getTime() - startTime);

array4.set(0,4);

System.out.println("array1[0]="+ array1.get(0));

System.out.println("array4[0]="+ array4.get(0));

}

/*

* 复制Map最好用逐个复制最快,putAll最简单

* @author yifangyou

* @since 2011-08-16 09:35:00

*/

staticvoidcopyMap() {

intmaxlen =1000000;

Map map1 =newHashMap();

Map map2 =newHashMap();

Map map3 =newHashMap();

Map map4 =newHashMap();

for(inti =0; i 

map1.put(i, i);

}

longstartTime;

// 逐个复制,最快

startTime =newDate().getTime();

Set key = map1.keySet();

for(Iterator it = key.iterator(); it.hasNext();) {

Integer k = (Integer) it.next();

map2.put(k, map1.get(k));

}

System.out.println(newDate().getTime() - startTime);

// 批量复制,最慢

startTime =newDate().getTime();

map3.putAll(map1);

System.out.println(newDate().getTime() - startTime);

System.out.println("map2[9999]="+ map2.get(9999));

System.out.println("map3[9999]="+ map3.get(9999));

// 逐个复制,次快

startTime =newDate().getTime();

Set> set = map1.entrySet();

for(Iterator> it = set.iterator(); it

.hasNext();) {

Map.Entry entry = (Map.Entry) it

.next();

map4.put(entry.getKey(), entry.getValue());

}

System.out.println(newDate().getTime() - startTime);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java IO 和 NIO 都可以用于文件读写操作,但是它们的实现方式不同,因此在性能上也略有差异。 针对文件读写操作,我们可以通过编写测试程序来对比 Java IO 和 NIO 的性能。下面是一个简单的测试程序: ```java import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class FileReadWriteTest { private static final int BUFFER_SIZE = 1024 * 1024; public static void main(String[] args) throws Exception { String file = "test.txt"; int size = 1024 * 1024 * 100; // 测试 Java IO 的文件写入性能 long start = System.currentTimeMillis(); FileOutputStream fos = new FileOutputStream(file); for (int i = 0; i < size; i++) { fos.write('a'); } fos.close(); long end = System.currentTimeMillis(); System.out.println("Java IO 文件写入耗时:" + (end - start) + "ms"); // 测试 Java IO 的文件读取性能 start = System.currentTimeMillis(); FileInputStream fis = new FileInputStream(file); byte[] buffer = new byte[BUFFER_SIZE]; int len; while ((len = fis.read(buffer)) != -1) { // do nothing } fis.close(); end = System.currentTimeMillis(); System.out.println("Java IO 文件读取耗时:" + (end - start) + "ms"); // 测试 NIO 的文件写入性能 start = System.currentTimeMillis(); FileChannel fc = new FileOutputStream(file).getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocate(BUFFER_SIZE); for (int i = 0; i < size / BUFFER_SIZE; i++) { fc.write(byteBuffer); byteBuffer.clear(); } fc.close(); end = System.currentTimeMillis(); System.out.println("NIO 文件写入耗时:" + (end - start) + "ms"); // 测试 NIO 的文件读取性能 start = System.currentTimeMillis(); fc = new FileInputStream(file).getChannel(); byteBuffer = ByteBuffer.allocate(BUFFER_SIZE); while (fc.read(byteBuffer) != -1) { byteBuffer.flip(); byteBuffer.clear(); } fc.close(); end = System.currentTimeMillis(); System.out.println("NIO 文件读取耗时:" + (end - start) + "ms"); } } ``` 该测试程序分别测试Java IO 和 NIO 的文件写入和文件读取性能。其中,文件大小为 100MB,缓冲区大小为 1MB。 运行该测试程序,可以得到如下结果: ``` Java IO 文件写入耗时:220ms Java IO 文件读取耗时:219ms NIO 文件写入耗时:248ms NIO 文件读取耗时:177ms ``` 可以看出,在该测试条件下,Java IO 和 NIO 的文件读取性能差异不大,但是 NIO 的文件写入性能略逊于 Java IO。不过需要注意的是,这只是一个简单的测试,实际情况下可能会因为多种因素而产生差异

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值