位运算效率高还是位运算效率高?

在《java程序性能优化》中写到,位运算是运算中最高效的,而我依照书上的代码运行了一遍
发现并不是这样。

补上代码:

public class BitOperate {

public static void main(String[] args) {
    nomal();
    bit();
}

private static void nomal() {
    long start =System.currentTimeMillis();
    long a = 100;
    for (int i = 0; i < 100000000; i++) {
        a*=2;
        a/=2;
    }
    System.out.println("nomal total used:"
            + (System.currentTimeMillis() - start) + "ms");
}

private static void bit() {
    long start =System.currentTimeMillis();
    long a = 100;
    for (int i = 0; i < 100000000; i++) {
        a<<=1;
        a>>=1;
    }
    System.out.println("bit total used:"
            + (System.currentTimeMillis() - start) + "ms");
}

}

输出:

nomal total used:1ms
bit total used:3ms

望能解惑

这和你机器当时的运行状态有关系,不代表实际情况,看我的测试结果

nomal total used:1864ms
bit total used:771ms

在很快的设备上,由于操作系统会进行任务调度,因此很多未知因素会导致出现偏差,要想真正准确测试,应该在单任务操作系统甚至裸机上测试,,
但位运算快是毫无疑问的
在手机上的arm处理器上,就比较明显了,如图:图片

和你的机器有关,但位运算确实是最快的

nomal total used:109ms
bit total used:8ms

我用你的代码测试结果是
nomal total used:321ms
bit total used:25ms
而你的都是1ms,3ms这些看起来几乎可以忽略不计的时间量。
所以可能是你的机子的确比我的快很多,然后100000000对于来说,差距不明显。
System.currentTimeMillis()本来就是精确到ms级别的,理论上误差<±1ms。
另外系统的运行状态存在不一样,算做存在干扰因素。
1ms的精度级别上,1ms和3ms的时间比较,干扰因素带来的干扰就比较大了。
另外,你的直接就1ms和3ms感觉比我的机器不要快太多了,加上你的a变量实际上没有用作其它用途,并且乘以2再除以2感觉更是多余,我不知道是不是你的“java编译器”自动把这个操作给优化掉了。好吧,java编译器已经暴露了我是个对java不太熟悉的家伙。所以这个仅仅是猜测。
另外下面是我把循环里的操作以及把循环去掉(代码如下)后再次运行结果:

nomal total used:315ms
bit total used:22ms
kkk total used:4ms
ddd total used:0ms

从这个结果可以看到与第一次运行结果(321ms,25ms)相比时间有了波动。

nomal total used:316ms
bit total used:26ms
kkk total used:5ms
ddd total used:0ms

nomal total used:314ms
bit total used:24ms
kkk total used:5ms
ddd total used:0ms

如上,可以很明显的看到时间波动几ms是有非常的可能的

另外,如果我的机子和你的性能相差不是很大的话,你的时间可能比较接近与自动把里面的a的运算优化掉了的时间(kkk)
当然,可能只是我的机子太老了才这么逊。(╥╯^╰╥)嘤嘤嘤

public class BitOperate {

public static void main(String[] args) {
    nomal();
    bit();
    kkk();
    ddd();
}

private static void nomal() {
    long start =System.currentTimeMillis();
    long a = 100;
    for (int i = 0; i < 100000000; i++) {
        a*=2;
        a/=2;
    }
    System.out.println("nomal total used:"
            + (System.currentTimeMillis() - start) + "ms");
}

private static void bit() {
    long start =System.currentTimeMillis();
    long a = 100;
    for (int i = 0; i < 100000000; i++) {
        a<<=1;
        a>>=1;
    }
    System.out.println("bit total used:"
            + (System.currentTimeMillis() - start) + "ms");
}

    private static void kkk() {
        long start =System.currentTimeMillis();
        long a = 100;
        for (int i = 0; i < 100000000; i++) {
        }
        System.out.println("kkk total used:"
                + (System.currentTimeMillis() - start) + "ms");
    }
    private static void ddd() {
        long start =System.currentTimeMillis();
        long a = 100;

        System.out.println("kkk total used:"
                + (System.currentTimeMillis() - start) + "ms");
    }

}