for(int i = 0 ; i < 1000 ;i++){
   for(int j = 0; i < 100; j++){
      for(int k = 0;k < 10; k++ ){
fun(i,j,k);
      }
    }
}
今天笔试的时候遇到这么一道题目  说有上面这么循环嵌套  ,问怎么优化 并说明原因。

解决方案 »

  1.   

    for( int k=0;k <10;k++){ 
          for(int j=0;j <100;j++){ 
            for(int i=0;i <1000;i++){ 
                    function(i,j,k); 
            } 
          } 
        }
    这样是不是效率会好点
      

  2.   

    下面内容是从另外一个帖子上看到的
    分析: 
        内大外小 
        for( int k=0;k <10;k++){ 
          for(int j=0;j <100;j++){ 
            for(int i=0;i <1000;i++){ 
                    function(i,j,k); 
            } 
          } 
        }  
        k <10;k++;    执行10次 
        j <100;j++    执行10*100次 
        i <1000;i++    执行10*100*1000次 
        function(i,j,k); 执行10*100*1000次 
        共执行语句数=(10+10*100+10*100*1000)*2+10*100*1000=3002020 
        内小外大 
        for( int k=0;k <1000;k++){ 
          for(int j=0;j <100;j++){ 
            for(int i=0;i <10;i++){ 
                    function(i,j,k); 
            } 
          } 
        }  
        k <1000;k++;  执行1000次 
        j <100;j++    执行1000*100次 
        i <10;i++      执行10*100*1000次 
        function(i,j,k); 执行10*100*1000次 
        共执行语句数=(1000+1000*100+10*100*1000)*2+10*100*1000=3202000 所以执行效率应该是内大外小更高一写 
                        内小外大-内大外小=3202000条语句-3002020条语句=199980条语句 http://topic.csdn.net/u/20080430/17/1427f647-8f08-4a88-aded-5b0e87f2cc60.html
      

  3.   

    中间的for循环 for(int j = 0; i < 100; j++) 是否 i写错了,否则 这是死循环,另外优化的意思,也就是在最终的结果 不改变的前提下,进行 性能上的优化。如果仅仅 是fun方法调用的次数来谈优化,那根本没有意义。在最终结果不变的前提下,fun方法的调用次数肯定要一样,就好比,5*4 = 20 与 4*5 = 20 一样。
    ===============================
    以上只是个人浅见。。如有异议,望少仍鸡蛋先。。
      

  4.   

    5楼说的有道理,应该从命中率上来分析,那20万条语句效率根本差不到哪儿去
    要看最后fun做了什么才能确定效率哪个高
      

  5.   

     。。我晕啊。 1/2/3/4楼的不是减少了应用次数了么。 这能叫优化??和源程序都不一样了啊。 支持5楼的兄弟。用while是不是好一些呢。  据说 JVM把for最终都是编译成while来执行的。 但是具体的就没考虑了。
      

  6.   

    long startTime = System.currentTimeMillis();
    int i =1000;
    int j=100;
    int k=10;
    int i1=0;
    int j1=0;
    int k1=0;
    for(int n=0;n<i*j*k;n++){
    if(n>0){
    if(n%(k*j) ==0){
    i1++;
    }
    if(n%k==0){
    j1++;
    }
    if(j1>=j){
    j1=0;
    }
    if(k1>=k){
    k1=0;
    }
    }
    System.out.println("I= " +i1 +" J= "+j1 +" K=" +k1++);
    }可以得到相同的结果,但发现性能好像没什么变化。。高手指教
    System.out.println(System.currentTimeMillis()-startTime);
      

  7.   

    用while测试了。 差不多。 测试了10次。while每次都比for少一秒。 很准的。哈哈。
      

  8.   

    如果是java语言,这题是没有答案的,不同的jdk实现优化方式不一样看看http://topic.csdn.net/u/20101112/15/4548c7ba-56bf-4b88-841e-47a8491be47f.html
    上面的帖子中,同样的代码,在IBM J9 1.5与IBM J9 1.6的jre中运行的结果是不一样的
    对于这样的大循环,IBM J9 1.6比sun hotspot和oracle的jrockit jdk的速度都快,然而IBM J9 1.5的实现效率很差如果是c语言,这个问题倒是还可以给出个答案
      

  9.   


    for(int i = 0 ; i < 1000000 ;i++)
    fun(i/1000%1000,i/10%100,i%10);
      

  10.   

    2楼说的不错,从算法上分析,确实是内大外小会更快一些,虽然最终f(i,j,k)执行次数是一样的,但不同的执行方法总次数不一样。
    Quote=引用 2 楼 mythofking 的回复:]
    下面内容是从另外一个帖子上看到的
    分析: 
      内大外小 
      for( int k=0;k <10;k++){ 
      for(int j=0;j <100;j++){ 
      for(int i=0;i <1000;i++){ 
      function(i,j,k); 
      } 
      } 
      }  
      k <10;k++; 执行10次 
      j <100;j++ 执行10*……
    [/Quote]
      

  11.   

    支持5楼,根本的东西没有抓住!fun调用次数不能变。
      

  12.   

    2楼误导public class Test1 { /**
     * @param args
     */
    public static void main(String[] args) {
    int x = 0;
    int y = 0;
    for (int k = 0; k < 10; k++) {
    for (int j = 0; j < 100; j++) {
    for (int i = 0; i < 1000; i++) {
    ++x;
    }
    }
    } for (int k = 0; k < 1000; k++) {
    for (int j = 0; j < 100; j++) {
    for (int i = 0; i < 10; i++) {
    ++y;
    }
    }
    }
    System.out.println("x=" + x);
    System.out.println("y=" + y); }
    }x=1000000
    y=1000000
      

  13.   

    18L说的没错。C语言中循环的嵌套,确实很影响系统性能。毕竟C语言写的东西都是系统级别或者嵌入式级别的程序,一点点的差异可能带来的最终影响非常大。java的范畴基本是应用程序层次,时间的关键度不是特别明显,但还是有的。该题目的核心,也就是要考察一下程序执行效率问题。最忙的循环要放在最里层去做,这样尽量减少CPU指令和调用栈的切换,以最大化CPU指令的流水线操作
      

  14.   

    看过C的一篇文章,这两种代码都要计较:
    代码1:
    for(int i = 0; i < 5000;i++){    if(a>10){
            //
        }
        else{    }
    }
    代码2:
    if(a>10){
        for(int i = 0; i < 5000;i++){    }
    }
    else{
        for(int i = 0; i < 5000;i++){    }
    }
      

  15.   

    个人认为 fro循环内大外小 在内存信息块的切换上的次数就相对减少,所以效率应该会更高些。
      

  16.   

    内小外大:
    k初始化100*1000次
    j初始化1000次
    内大外小:
    k初始化10*100
    j初始化10次
    很明显内大外小更好一些,在JAVA中所有的赋值语句、比较语句、++语句这些都会转换成进栈、出栈、比较、加等各种指令。
    也就是说内小外大内大外小多执行很多JVM指令(因为一个简单的int i,int j之类的变量声明,编译成JVM指令后,可不只是一条指令)。
    以上代码可以优化成:int i=0;
    int j=0;
    int k=0;
    for(i=0;i<10;i++){
       for(j=0;j<100;j++){
          for(k=0;k<1000;k++){
            fun(i,j,k);
          }
       }
    }fun()被调用的次数虽然相同,但不意味着程序的效率相同。发现问题,要多思考
      

  17.   

    这种jvm实现太垃圾了吧,离开了作用域的j、k在下一次循环中可以重用嘛,为什么要丢弃还不断的分配?重用,这才是一个好的jvm应该做的!
      

  18.   

    没办法,Sun公司已经很牛了,虽然被Oracle收购了。
    就是.net来讲没有JVM
    还是会有初始化变量时的占用内存-->释放内存的重复操作。
      

  19.   

    去试试IBM J9 1.5和IBM J9 1.6,两者跑出的结果大相径庭,甚至让你瞠目结舌
      

  20.   

    真是感触颇深。本人还是一个初学者。关于两楼说的
      k <10;k++; 执行10次  
      j <100;j++ 执行10*100次  
      i <1000;i++ 执行10*100*1000次  
      function(i,j,k); 执行10*100*1000次  
      共执行语句数=(10+10*100+10*100*1000)*2+10*100*1000=3002020  
    一共执行语句数,不太明白!
    内大外小和内小外大,最终如果输入的次数应该是一样的吧,一共都是10*100*1000次?而您所说的共执行语句次数不太明白。大虾,请详细说明一下。谢谢啦!
      

  21.   

    呵呵 我来给大家换个思路,这三个循环嵌套其实根本没有意义啊它要表示的无非就是三个变量之间的关系而已我们何不直接一点呢?这样写:k=10
    i=1000
    j=100
    fun(i,j,k)当然如果从算法的角度应该是如何降低 时/空复杂度 没仔细看 就不写了