首页 文章

为什么布尔逻辑运算符^在Effective Java的这段示例代码中使用?

提问于
浏览
1

我找到this example code为Joshua Bloch 's book, Effective Java. It' s意味着要证明为什么你应该避免不必要地创建对象:

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();
    }
}

为什么boolean logical operator ^在主方法中的for循环中使用?

是否阻止编译器优化掉后续迭代(从而影响测量),因为结果无论如何都是相同的?

1 回答

  • 2

    你的猜测可能是正确的 . ^= 运算符和最后的if语句都是为了防止编译器/运行时优化 .

    最初 b 为假, b ^= trueb 赋值为真,然后 b ^= trueb 赋予false,循环继续 .

    通过使 b 循环通过true和false,使编译器更难以优化它,因为它没有看到常量值 .

    ^ 的另一个属性是必须评估两个操作数以便评估结果,这与 ||&& 不同 . 运行时无法使用快捷方式 .

    最后的if语句告诉编译器和运行时:“不要忽略 b !它在以后很重要!” .

相关问题