關於取餘運算比位運算效率哪個高的思考

1.最初是有一道題,寫一個方法返回是否奇偶數。

題目如下。

https://www.codingsky.com/doc/2020/3/22/929.html

最終我寫了如下測試代碼


public class Main {
    public static void main(String[] args) {

        test1();
        test2();

    }

    public static void test1() {
        int number = Integer.MAX_VALUE;//分別取值10萬、100萬、1000萬、1億
        int a = 1;
        long start = System.currentTimeMillis();
        for (int j = 1; j < number; j++) {
            for (int i = 1; i < number; i++) {
            boolean ret = isOdd(i);
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("第1種" +(end - start) + "毫秒");
    }

    public static void test2() {
        int number = Integer.MAX_VALUE;//分別取值10萬、100萬、1000萬、1億
        int a = 1;
        long start2 = System.currentTimeMillis();
        for (int j = 1; j < number; j++) {
            for (int i = 1; i < number; i++) {
             boolean ret2 = isOdd2(i);
            }
        }
        long end2 = System.currentTimeMillis();
        System.out.println("第2種" + (end2 - start2) + "毫秒");
    }
    public static boolean isOdd(int i) {
        return i % 2 != 0;
    }
    public static boolean isOdd2(int i) {
        return (i & 1) == 1;
    }
}

測試好多次,結論果然如上文章所說,兩種差不多

二、但同時網上也有人給出結論說

位運算與 和取模運算 &比%具有更高的效率

https://blog.csdn.net/kris1025/article/details/104577813

關鍵代碼

public class Main {
    public static void main(String[] args) {

        test1();
        test2();

    }

    public static void test1() {
        int number = Integer.MAX_VALUE;//分別取值10萬、100萬、1000萬、1億
        int a = 1;
        long start = System.currentTimeMillis();

            for (int i = 1; i < number; i++) {
                a %= i;
            }
        long end = System.currentTimeMillis();
        System.out.println("第1種" +(end - start) + "毫秒");
    }

    public static void test2() {
        int number = Integer.MAX_VALUE;//分別取值10萬、100萬、1000萬、1億
        int a = 1;
        long start2 = System.currentTimeMillis();
            for (int i = 1; i < number; i++) {
              a &= i;
            }
        long end2 = System.currentTimeMillis();
        System.out.println("第2種" + (end2 - start2) + "毫秒");
    }

我親自運行代碼測試了下,也是正確的。

那到底誰對呢?

後來我又發現其實上面說取模運算快的,例子取餘的數一直在變。也就是上面的i。

而求奇偶數中餘上的數固定是2.

這裏又研究看到了另二篇文章,才明白原因。

這裏貼下結論

通過原理來計算取餘和取模總結

  • fix 函數是向 0 方向舍入取整,取餘操作計算餘數步驟爲:
    • n=fix(x除以y)
    • rem(x,y)=x-n*y

參考如下:

https://mp.csdn.net/console/editor/html/106809391

再結合計算機乘法,和除法的計算原理。

https://www.cnblogs.com/stigerzergold/p/10328472.html 

最終才知道兩者爲何原因。是因爲求餘,會轉換爲除法和乘法。所以餘數大了,計算機底層的操作步驟就多了。所以運算的耗時。

所以把上述代碼改成如下。你會發現時間也差不多。

public class Main {
    public static void main(String[] args) {
//        for (int i = 0; i < 10; i++) {
//
//        }

        test1();
        test2();

    }

    public static void test1() {
        int number = Integer.MAX_VALUE;//分別取值10萬、100萬、1000萬、1億
        int a = 1;
        long start = System.currentTimeMillis();
        for (int j = 1; j < number; j++) {
            for (int i = 1; i < number; i++) {
//            boolean ret = isOdd(i);
                a = i % 2;
                // n = i/2(左移<<1), a = i - (n * 2)
                // a = i - (i << 1 >> 1);
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("第1種" +(end - start) + "毫秒");
    }

    public static void test2() {
        int number = Integer.MAX_VALUE;//分別取值10萬、100萬、1000萬、1億
        int a = 1;
        long start2 = System.currentTimeMillis();
        for (int j = 1; j < number; j++) {
            for (int i = 1; i < number; i++) {
//             boolean ret2 = isOdd2(i);
                a = i & 1;
            }
        }
        long end2 = System.currentTimeMillis();
        System.out.println("第2種" + (end2 - start2) + "毫秒");
    }

 後面再附一個位運算的奇技淫巧

https://www.zhihu.com/question/38206659

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章