简体   繁体   中英

Why is the boolean logical operator ^ being used in this piece of example code from Effective Java?

I found this example code for Joshua Bloch's book, Effective Java. It's meant to demonstrate why you should avoid unnecessarily creating objects:

import java.util.regex.Pattern;

// Reusing expensive object for improved performance
public class RomanNumerals {
    // Performance can be greatly improved!
    static boolean isRomanNumeralSlow(String s) {
        return s.matches("^(?=.)M*(C[MD]|D?C{0,3})"
                + "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
    }

    // Reusing expensive object for improved performance (Page 23)
    private static final Pattern ROMAN = Pattern.compile(
            "^(?=.)M*(C[MD]|D?C{0,3})"
                    + "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");

    static boolean isRomanNumeralFast(String s) {
        return ROMAN.matcher(s).matches();
    }

    public static void main(String[] args) {
        int numSets = Integer.parseInt(args[0]);
        int numReps = Integer.parseInt(args[1]);
        boolean b = false;

        for (int i = 0; i < numSets; i++) {
            long start = System.nanoTime();
            for (int j = 0; j < numReps; j++) {
                b ^= isRomanNumeralSlow("MCMLXXVI");  // Change Slow to Fast to see performance difference
            }
            long end = System.nanoTime();
            System.out.println(((end - start) / (1_000. * numReps)) + " μs.");
        }

        // Prevents VM from optimizing away everything.
        if (!b)
            System.out.println();
    }
}

Why is the boolean logical operator ^ being used in the for loop inside the main method here?

Is it to prevent the compiler from optimizing away subsequent iterations (thereby compromising the measurement), since the result would anyway be the same?

Your guess is probably right. The ^= operator and the if statement at the end are both to prevent compiler/runtime optimisations.

Initially b is false, b ^= true assigns true to b , then b ^= true assigns false to b , and the cycle continues.

By making b cycle through true and false, it makes it harder for the compiler to optimise this because it doesn't see a constant value.

Another property of ^ is that both operands must be evaluated in order to evaluate the result, unlike || or && . The runtime can't take shortcuts.

The if statement at the end is telling the compiler and the runtime: "don't ignore b ! It is of important use later!".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM