为什么在 Effective Java 的这段示例代码中使用布尔逻辑运算符 ^?
Why is the boolean logical operator ^ being used in this piece of example code from Effective Java?
我找到了 this example code Joshua Bloch 的书 Effective 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();
}
}
为什么boolean logical operator ^被用在main方法里面的for循环中?
这是为了防止编译器优化后续迭代(从而影响测量),因为结果无论如何都是一样的?
您的猜测可能是正确的。 ^=
运算符和末尾的 if 语句都是为了防止 compiler/runtime 优化。
最初b
为false,b ^= true
将true赋给b
,然后b ^= true
将false赋给b
,如此循环。
通过使 b
在 true 和 false 之间循环,编译器更难对其进行优化,因为它看不到常量值。
^
的另一个属性是必须计算两个操作数才能计算结果,这与||
或&&
不同。运行时不能走捷径
末尾的 if 语句告诉编译器和运行时:"don't ignore b
! It is of important use later!"。
我找到了 this example code Joshua Bloch 的书 Effective 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();
}
}
为什么boolean logical operator ^被用在main方法里面的for循环中?
这是为了防止编译器优化后续迭代(从而影响测量),因为结果无论如何都是一样的?
您的猜测可能是正确的。 ^=
运算符和末尾的 if 语句都是为了防止 compiler/runtime 优化。
最初b
为false,b ^= true
将true赋给b
,然后b ^= true
将false赋给b
,如此循环。
通过使 b
在 true 和 false 之间循环,编译器更难对其进行优化,因为它看不到常量值。
^
的另一个属性是必须计算两个操作数才能计算结果,这与||
或&&
不同。运行时不能走捷径
末尾的 if 语句告诉编译器和运行时:"don't ignore b
! It is of important use later!"。