`

关于JAVA for循环效率的问题

 
阅读更多

今天在C#里面看到:
之前一直认为
for (int i = 0, h = arr.Count; i < h; i++)

for (int i = 0; i < arr.Count; i++)
两种写法,在C#里应该是差不多的,今天突然有人问,就写了个程序测试了一下,结果出乎我的意料
如果arr是List<T>,前者的效率比后者高大约一倍,如果arr是string[],两者效率基本差不多

原帖子地址:http://topic.csdn.net/u/20120706/16/CEB33682-FF71-402C-9FE9-580F5ECFDFC1.html

我写的代码测试:int tnum = 1000000; // 添加或查找的次数
int outnum = 10; // 外层循环次数
ArrayList<String> arr = new ArrayList<String>();
for (int i = 0; i < tnum; i++) {
arr.add(Integer.toString(i));
}
String[] arr2 = new String[tnum];
for(int j=0;j<outnum;j++)
{
Long time = System.currentTimeMillis();
String msg;
    msg = "Number ";
    for (int i = 0, h = arr.size(); i < h; i++)
    {
    }
   time = System.currentTimeMillis()-time;
   System.out.println(msg+"耗时:"+time);

    msg = ".Count ";
    time = System.currentTimeMillis();
    for (int i = 0; i < arr.size(); i++)
    {
    }
    time = System.currentTimeMillis()-time;
    System.out.println(msg+"耗时:"+time);

    msg = "Length ";
    time = System.currentTimeMillis();
    for (int i = 0; i < arr2.length; i++)
    {
    }
    time = System.currentTimeMillis()-time;
    System.out.println(msg+"耗时:"+time);
}
我发现时间都差不多啊,难道是因为ArrayList的原因?还是JAVA这个用的时间本来就是一样的?

============================================================================

LZ这样比较是很难看出来的,还是查看伪代码指令比较好理解

Java code?
1
2
3
4
5
6
7
8
import java.util.*;
public class jp {
    public static void main(String[] args) throws Throwable {
        List<String> list = new ArrayList<String>();
        for (int i=0, j=list.size(); i<j; i++); //list.size()只调用一次
        for (int i=0; i<list.size(); i++); //list.size()每次都调用
    }
}



javac jp.java //编译
javap -c jp //查看伪代码指令

E:\Test>javap -c jp
Compiled from "jp.java"
public class jp {
  public jp();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":
()V
       4: return

  public static void main(java.lang.String[]) throws java.lang.Throwable;
    Code:
       0: new           #2                  // class java/util/ArrayList
       3: dup
       4: invokespecial #3                  // Method java/util/ArrayList."<init
>":()V
       7: astore_1
       8: iconst_0
       9: istore_2
      10: aload_1
      11: invokeinterface #4,  1            // InterfaceMethod java/util/List.si
ze:()I
      16: istore_3
      17: iload_2
      18: iload_3
      19: if_icmpge     28
      22: iinc          2, 1
      25: goto          17

      28: iconst_0
      29: istore_2
      30: iload_2
      31: aload_1
      32: invokeinterface #4,  1            // InterfaceMethod java/util/List.si
ze:()I
      37: if_icmpge     46
      40: iinc          2, 1
      43: goto          30

      46: return
}

红色部分是第一种循环情况
8: iconst_0把0入栈
9: isrote_2把0出栈并赋给2号索引变量i,即i=0操作,1号索引变量是list,即前面的astore_1把ArrayList对象赋给1号索引变量
10: aload_1把1号索引变量入栈,即list入栈
11: invokeinterface把list出栈并调用其size方法,把结果入栈
16: istore_3把size方法的结果出栈并赋给3号索引变量j,即j=list.size()操作
17: iload_2
18: iload_3 把2,3号索引变量入栈
19: if_icmpge     28 比较入栈的两个数据,前者大于等于后者则跳转到28行指令,即不满足i<j跳转
22: iinc          2, 1 2号索引变量i自增1
25: goto          17 跳转到17行指令,即for重新开始循环


蓝色部分是第二种情况(循环体)
28:iconst_0 0入栈
29:istore_2 0出栈并赋给i
30:iload_2 i入栈
31:aload_1 list入栈
32:invokeinterface list出栈并调用size方法,把结果入栈
37: if_icmpge     46 比较入栈的两个数据,前者大于等于后者则跳转到46行指令,即不满足i<list.size
40: iinc          2, 1 2号索引变量i自增1
43: goto          30 跳转到30行指令,即for重新开始循环


比较可以看出,第一种情况,list.size只需要执行一次,第二种则每次循环都要执行

分享到:
评论

相关推荐

    js,java提高编程效率之【for循环优化】.pdf

    js,java提高编程效率之【for循环优化】

    Java for循环性能优化实现解析

    主要介绍了Java for循环性能优化实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    for循环中如何正确使用字符串拼接

    那么通过如下代码,看一下在for循环中,不同的字符串拼接方式,到底哪种效率最高?  package com.test.stringjoin; import org.apache.commons.lang3.StringUtils; public class Test { public static void main...

    java快捷键

    Ecplise所有使用的快键键,方便快速写java代码,提高效率

    《JAVA语言程序设计》期末考试试题及答案6(应考必备题库)

    3.关于 for循环和 while循环的说法哪个正确? ( ) A.while循环先判断后执行,for循环先执行后判断。 B.while循环判断条件一般是程序结果,for循环的判断条件一般是非程序结果 C.两种循环任何时候都不可以...

    javascript for循环从入门到偏门(效率优化+奇特用法)

    一,for循环的基本写法 代码如下: 代码如下: //例一for(var i=1;i&lt;=10;i++) { alert&#40;i&#41;; } 这段代码太简单了,我都不好意思拿出手。代码的执行结果是依次弹出1到10,PS:在早期的IE如IE6中,你把10改成...

    Java经典编程源码基础例程300.zip

    实例025 使用for循环输出杨辉三角形 34 实例026 使用嵌套循环在控制台上 输出九九乘法表 35 实例027 使用while循环计算1+ 1/2!+1/3!…1/20! 36 实例028 使用for循环输出空心的菱形 38 实例029 终止循环体 39 实例...

    JAVA 编码规范

    1命名规则 3 1.1 共性规则 3 1.2 应用程序命名规则 4 ...3.4 for 语句的循环控制变量 14 3.5 switch语句 15 3.6 变量的初始化 15 4参数命名规范 15 5异常处理规范 16 6附录1 17 7附录2: Java编程参考 17

    java基础 经典算法之冒泡排序详解

    2.通过画图分析,5个数字排4趟,n数字排n-1趟,而外层的for循环代表的是循环的趟数,所以外层循环的结束条件是array.length-1,但是写array.length代码也没有问题,比如5个数字在第4趟都已经排好了,再进行第5趟排序,也不会...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    Java编程老鸟潜心写作,奉献高效率的Java学习心得 完全站在没有编程经验读者的角度,手把手教会读者学习Java 配16小时多媒体教学视频,高效、直观 一一击破Java入门可能会遇到的难点和疑惑 抽丝剥茧,层层推进,让...

    求出1到1000的所有完全数.java

    利用Java编写程序,求出1到1000的所有完全数,完全数是其所有因子(包括1但不包括本身)的和等于该数 ,例如,28=1+2+4+7+14,28就是一个完全数

    java程序计算24点 递归算法 解决括号问题

    *计算24点 难点是递归算法归纳(双重for循环加递归啊 容易蒙) 以及加括号(完美解决)问题 *不限于4个数 但6个数时 运行已经相当吃力 *程序逻辑竭力去除重复解(加法乘法交换律 不算重复) 但无法完全 最后只能以Set ...

    java组装树形结构demo.7z

    java组装树形结构数据小技巧,巧妙利用java的对象引用特点,仅使用2层for循环即可组装深层树形结构数据;比传统的自循环组装树形数据,效率更高更实用;

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    Java编程老鸟潜心写作,奉献高效率的Java学习心得 完全站在没有编程经验读者的角度,手把手教会读者学习Java 配16小时多媒体教学视频,高效、直观 一一击破Java入门可能会遇到的难点和疑惑 抽丝剥茧,层层推进,让...

    Java精华(免费版)

    (2)在没次循环中,都只是调用原来的那个stringbuffer对象,没有创建新的对象,所以效率比较高。 1.1.1.2System类与Runtime类 由于java不支持全局函数和全局变量,所以java设计者将一些与系统相关的重要函数和变量...

    达内 coreJava 习题答案

    4、利用for循环打印 9*9 表? 1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*...

    java代码优化

    4、与for循环有关的性能问题 5、与集合类有关的性能问题 6、与开发有关的性能问题 7、与工具方法有关的性能问题 8、与sql动态绑定有关的性能问题 9、与反射调用有关的性能问题 10、缓存使用的性能问题 11、并发锁...

    javascript for循环性能测试示例

    for循环,如何使用效率更高,下面举例来说明: // 先定义一个测试数组 var arr = [0,1,2,3,4,5,6,7,8,9]; // 执行测试 test1(); test2(); test3(); function test1(){ console.time('test1'); for(var i = 0; i &...

    跟我学Java面向对象程序设计技术及应用——识别某个自然数是否为质数(素数)的Java程序实现示例.doc

    } } } } 示例程序中的循环只需要从自然数2开始(for循环中的int loopCounterInt=2定义),一直循环到小于所识别的数字其自身就可以结束循环。因为 小于等于3的自然数只有2和3是质数。 (2)源程序截图 5、在...

    java 面试题 总结

     GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收...

Global site tag (gtag.js) - Google Analytics