日期:2014-05-20  浏览次数:20775 次

关于移位和直接相乘的问题
Java code
int x = 1, y;
        y = 0;
        long time;
        for(int k=0; k<8; k++) {
            time = System.currentTimeMillis();
            for(long j=0; j<2000000000; j++)
                y = 2 * x;
            System.out.println("所用时间1:" + (System.currentTimeMillis() - time));       
            
            time = System.currentTimeMillis();
            for(long j=0; j<2000000000; j++)
                y = x << 1;
            System.out.println("所用时间2:" + (System.currentTimeMillis() - time));
            
            System.out.println();
        }

程序运行结果
所用时间1:10312
所用时间2:8782

所用时间1:9562
所用时间2:8734

所用时间1:10047
所用时间2:8766

所用时间1:10047
所用时间2:9078

所用时间1:9859
所用时间2:9141
Java code
int x = 1, y;
        y = 0;
        long time;
        for(int k=0; k<8; k++) {
            time = System.currentTimeMillis();
            for(long j=0; j<2000000000; j++)
                y = x << 1;
            System.out.println("所用时间1:" + (System.currentTimeMillis() - time));       
            
            time = System.currentTimeMillis();
            for(long j=0; j<2000000000; j++)
                y = 2 * x;                
            System.out.println("所用时间2:" + (System.currentTimeMillis() - time));
            
            System.out.println();
        }

结果:
所用时间1:10000
所用时间2:8703

所用时间1:9188
所用时间2:8468

所用时间1:9969
所用时间2:9125

所用时间1:9891
所用时间2:8875

所用时间1:9906
所用时间2:9125

我想问下为什么放在后面的表达式所用的时间更短。


------解决方案--------------------
这问题高深了。。静候高人。。
------解决方案--------------------
我觉得不是放在代码前后的问题,本来就移位就应该比用*,/,+,-快!您再仔细审核一下程序。
------解决方案--------------------
如果在跑这个测试程序的时候同时机器用做其他的事情,可能会受一定的影响。楼主的程序在我的机器上跑了下,没干其他的事情,基本上,直接的位移运算是要比累乘快一点点的。
------解决方案--------------------
探讨
我觉得不是放在代码前后的问题,本来就移位就应该比用*,/,+,-快!您再仔细审核一下程序。

------解决方案--------------------
我只发现一点,那就是for循环是时间的焦点,第一个for循环会很慢。原因未知!
------解决方案--------------------
探讨
我只发现一点,那就是for循环是时间的焦点,第一个for循环会很慢。原因未知!

------解决方案--------------------
移位是直接运算了
而*它是通过一系列的移位运算得来的,当然要慢了
------解决方案--------------------
确实是这样的啊~~~

在程序在jvm的作用下运行时,*2的操作会被优化成移位操作,所以这两个的运行时间是一样的,如果将程序单独写在两个类中单独运行,时间基本相同。
Java code
所用时间1:5953
所用时间1:5953
所用时间1:5937
所用时间1:5953
所用时间1:5954
------
所用时间2:5969
所用时间2:5953
所用时间2:5968
所用时间2:5954
所用时间2:5968
------执行时间基本相同

------解决方案--------------------
这个要学习
------解决方案--------------------
基本上搞明白了,但有一些不清楚的地方,我的结论是,
1、如果连续两个相邻的相类似的结构的循环,java会做某种优化,具体怎么优化的不太清楚。
2、对于循环体比较简单的循环,时间大部分花在了循环控制上。
3、+,-,*这样的运算,时间差不多,区别不是太大。但/和%运算花的时间是前者7~8倍之多。
4、for(long n=200000000;n>0;n--)这种结构的循环,在循环控制上花的时间,是与之相反的循环的近一倍。
看我的测试:
Java code
public class test6{
    public static void main(String [] args) {
        int x = 333333333, y;
        y = 0;
        long time;
        for(int k=0; k<8; k++) {
            time = System.currentTimeMillis();
            for(long j=0; j<2000000000; j++)
                y = x *5;
            System.out.println("所用时间1:" + (System.currentTimeMillis() - time));  
            //****插入下面这个循环,目的是使前后两循环在执行顺序上相隔开。打乱java的优化。    
            for(long m=10000;m>1000;m--){
                for(int n=0;n<100000;n++);
            }
            time = System.currentTimeMillis();
            for(long j=0; j<2000000000; j++)
                y =  x<<2;                
            System.out.println("所用时间2:" + (System.currentTimeMillis() - time));
            
            System.out.println();
        }
    }
}