Почему логический оператор ^ используется в этом примере кода из Effective Java? - PullRequest
0 голосов
/ 09 декабря 2018

Я нашел этот пример кода для книги Джошуа Блоха "Эффективная Java".Он предназначен для демонстрации того, почему вы должны избегать ненужного создания объектов:

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

Почему логический оператор ^ используется здесь в цикле for внутри метода main?

Предотвращает ли компилятор оптимизацию последующих итераций (что ставит под угрозу измерение), поскольку результат в любом случае будет таким же?

1 Ответ

0 голосов
/ 09 декабря 2018

Ваше предположение, вероятно, верно.Оператор ^= и оператор if в конце предназначены для предотвращения оптимизаций компилятора / среды выполнения.

Первоначально b имеет значение false, b ^= true присваивает true b, затем b ^= true присваивает falseв b, и цикл продолжается.

Если b циклически переключаться между значениями true и false, компилятору будет сложнее оптимизировать это, поскольку он не видит постоянного значения.

Другое свойство ^ заключается в том, что оба операнда должны оцениваться для оценки результата, в отличие от || или &&.Среда выполнения не может использовать ярлыки.

Оператор if в конце говорит компилятору и среде выполнения: «Не игнорируйте b! Это важно позже!».

...