簡體   English   中英

為什么Java中的“或”慢於“和”?

[英]Why is “or” slower than “and” in Java?

今天,我在java中遇到了相當驚人的行為, or慢於and

我甚至做了一個你可以在下面看到的測試用例。現在我想知道為什么會這樣? 我做錯了什么或者只是在我的電腦上發生了什么? 我看不出有任何理由, or應慢and特意用這個顯著差異。 我想用其他一些語言測試這種現象,你對這個一般有什么想法嗎?

public class TestClass {

    public static void main(String[] args) {

        long[] or = new long[10];
        long[] and = new long[10];
        long lStartTime, lEndTime, difference = 0;
        for (int idx = 0; idx < 10; idx++) {

            lStartTime = System.nanoTime();
            for (int i= 0; i < 1000000000; i++) { 
                int j = i | i+1 ;
            }
            lEndTime = System.nanoTime();
            difference = lEndTime - lStartTime;
            System.out.println("Elapsed milliseconds: " + difference/1000000);
            or[idx] = difference;

            lStartTime = System.nanoTime();
            for (int i= 0; i < 1000000000; i++) {
                int j = i & i+1 ;
            }
            lEndTime = System.nanoTime();
            difference = lEndTime - lStartTime;
            System.out.println("Elapsed milliseconds: " + difference/1000000);  
            and[idx] = difference;
            System.out.println("------------------------------------" );

        }

        long tmp = 0;
        for (long l : or) {
            tmp += l;
        }
        tmp /= 10;
        System.out.println("Elapsed milliseconds for or: " + tmp/1000000);
        tmp = 0;
        for (long l : and) {
            tmp += l;
        }
        tmp /= 10;
        System.out.println("Elapsed milliseconds for and: " + tmp/1000000);
    }
}

結果:

Elapsed milliseconds: 1600
Elapsed milliseconds: 1332
------------------------------------
Elapsed milliseconds: 1609
Elapsed milliseconds: 1335
------------------------------------
Elapsed milliseconds: 1609
Elapsed milliseconds: 1335
------------------------------------
Elapsed milliseconds: 1542
Elapsed milliseconds: 1314
------------------------------------
Elapsed milliseconds: 1705
Elapsed milliseconds: 1324
------------------------------------
Elapsed milliseconds: 1559
Elapsed milliseconds: 1315
------------------------------------
Elapsed milliseconds: 1526
Elapsed milliseconds: 1314
------------------------------------
Elapsed milliseconds: 1568
Elapsed milliseconds: 1340
------------------------------------
Elapsed milliseconds: 1551
Elapsed milliseconds: 1318
------------------------------------
Elapsed milliseconds: 1574
Elapsed milliseconds: 1321
------------------------------------
Elapsed milliseconds for or: 1584
Elapsed milliseconds for and: 1325

Bit-Wise OR 並不比Bit-Wise AND慢!

在代碼中的時間測量片段之間切換,您將得到相反的結果:

for (int idx = 0; idx < 10; idx++) {

    lStartTime = System.nanoTime();
    for (int i= 0; i < 1000000000; i++) {
        int j = i & i+1 ;
    }
    lEndTime = System.nanoTime();

    difference = lEndTime - lStartTime;
    System.out.println("Elapsed milliseconds: " + difference/1000000);  
    and[idx] = difference;

    lStartTime = System.nanoTime();
    for (int i= 0; i < 1000000000; i++) { 
        int j = i | i+1 ;
    }
    lEndTime = System.nanoTime();

    difference = lEndTime - lStartTime;
    System.out.println("Elapsed milliseconds: " + difference/1000000);
    or[idx] = difference;

    System.out.println("------------------------------------");
}

我傾向於猜測JVM在第二個片段中應用了某種運行時優化。

編寫正確的微基准測試非常耗時且容易出錯。 我建議使用像Caliper這樣的現有庫。

這是在Caliper中完成的相應基准測試(編譯時需要的最新git版本):

public class BitwiseOperatorPerformance {
    @Benchmark
    public int timeOr(int reps){
        int dummy = 0;
        for (int i = 0; i < reps; i++) {
            dummy |= i+1;
        }
        return dummy;
    }
    @Benchmark
    public int timeAnd(int reps){
        int dummy = 0;
        for (int i = 0; i < reps; i++) {
            dummy &= i+1;
        }
        return dummy;
    }
}

這是測試結果: 鏈接

結果表明, AND和OR運算符的性能完全相同

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM