论坛首页 入门技术论坛

一道简单的面试题

浏览 29495 次
该帖已经被评为新手帖
作者 正文
   发表时间:2010-04-04  
   前几天有位朋友跟我聊天说,最近他去面试遇到一个面试题,叫我帮他分析一下,是一道Java的面试题目;题目是这样的:请对以下的代码进行优化
原题代码如下
for (int i = 0; i < 1000; i++)
   for (int j = 0; j < 100; j++)
       for (int k = 0; k < 10; k++)
           log(i * j * k);

对于以上的代码,我给出了两个优化方案,优化一代码如下
for (int i = 0; i < 10; i++)
   for (int j = 0; j < 100; j++)
       for (int k = 0; k < 1000; k++)
           log(i * j * k);

优化二代码如下
int i, j, k;
for (i = 0; i < 10; i++)
   for (j = 0; j < 100; j++)
       for (k = 0; k < 1000; k++)
           log(i * j * k);

首先先来分析一下这三段代码,如下三个表
原题代码分析表
变量实例化(次数)初始化(次数)比较(次数)自增(次数)
i1110001000
j100010001000 * 1001000 * 100
k1000 * 1001000 * 1001000 * 100 * 101000 * 100 * 10

优化一代码分析表
变量实例化(次数)初始化(次数)比较(次数)自增(次数)
i111010
j101010 * 10010 * 100
k10 * 10010 * 10010 * 100 * 100010 * 100 * 1000

优化二代码分析表
变量实例化(次数)初始化(次数)比较(次数)自增(次数)
i111010
j11010 * 10010 * 100
k110 * 10010 * 100 * 100010 * 100 * 1000

    从以上三个表的分析看,优化一的性能和优化二比原代码性能好,其中优化二的性能是最好的。从而也可以说在以上的条件下,将大的循环放在内侧,小的循环放在外侧,其性能会提高;减少变量的实例化,其性能也会提高。对于以上的优化,如果在循环次数少的情况下,其运行出来的效果不大;而在循环次数较多的情况下,则其效果是比较明显的。
    以上是我自己对该题的一个优化和分析,如果大家有更好的优化方法或我又错误的地方,请大家多多指教。
   发表时间:2010-04-04  
优化过的代码和原来的代码的输出结果是不是不一样了?log总次数一样,但顺序是不一样的。

i、j和k可以从1开始遍历,它们只要其中一个为0,i*j*k必然为0,这样会减少一些运算
0 请登录后投票
   发表时间:2010-04-04  
我是不是眼花了...优化代码一好像和优化代码二 一样的...
0 请登录后投票
   发表时间:2010-04-04  
magicway 写道
我是不是眼花了...优化代码一好像和优化代码二 一样的...

优化代码一是把变量实例化放在for循环里面,而优化代码二则是放在for循环外,所以你可以在表二和表三看到变量的实例化的次数是不相同的
1 请登录后投票
   发表时间:2010-04-04  
langqing 写道
优化过的代码和原来的代码的输出结果是不是不一样了?log总次数一样,但顺序是不一样的。

i、j和k可以从1开始遍历,它们只要其中一个为0,i*j*k必然为0,这样会减少一些运算


一点启发
这样的话 k 从 2 开始遍历
因为 k = 1 还是 i*j
int i, j, k;  
for (i = 0; i < 10; i++)  
   for (j = 1; j < 100; j++)  
       for (k = 2; k < 1000; k++)  
           log(i * j * k);  

0 请登录后投票
   发表时间:2010-04-04   最后修改:2010-04-05
 int i, j, k;    
 for (i = 0; i < 10; i++) 
{      
    if(i==0)  
    {
       log(0) ;
       continue;
    }
   else
    {   
       for (j = 1; j < 100; j++)    
         for (k = 1; k < 1000; k++)    
             log(i * j * k); 
     }
}
 

 

0 请登录后投票
   发表时间:2010-04-04  
linghongli 写道
 int i, j, k;    
 for (i = 0; i < 10; i++) 
{      
    if(i==0)  
    {
       log(0) ;
       break;
    }
   else
    {   
       for (j = 1; j < 100; j++)    
         for (k = 1; k < 1000; k++)    
             log(i * j * k); 
     }
}
 

 

有问题吧!这个布瑞克。

0 请登录后投票
   发表时间:2010-04-05  
至于优化二、优化三,对于Java/C这样的语言来说,应该是一样的。局部变量都不存在实例化的问题,因为它是在堆栈中分配的,在函数入口时就确定好了位置了。

换个加法试一试。

for (int i = 0; i < 10; i++)
   for (int j = 0; j < 100; j++) {
       int ij = i * j;
       int s = 0 - ij;
       for (int k = 0; k < 1000; k++)
           log(s+=ij);
   }
0 请登录后投票
   发表时间:2010-04-05  
想起某位大师关软件优化的一段话:

1、编写代码时,不要进行优化。
2、如果没有给你带来麻烦,就不要优化。

说实在的,上面的代码,在99%的情况下,是不需要进行优化的。如果你的情况正好是那个1%,那么你
0 请登录后投票
   发表时间:2010-04-05  
实例化次数计算不对,对于java来说,for语句的初始化只是执行一次。所以对于原代码,优化一和优化二实例化变量的实例化次数都是一。不对之处,多多指教。
1 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics