javac有多聪明?
如果我用javac编译下面的代码,编译器是否足够聪明,只对codeInput.length()进行一次计算,或者通过将受迭代器变量影响的计算放在首位,我是否可能获得更快的程序javac有多聪明?,java,compiler-construction,javac,Java,Compiler Construction,Javac,如果我用javac编译下面的代码,编译器是否足够聪明,只对codeInput.length()进行一次计算,或者通过将受迭代器变量影响的计算放在首位,我是否可能获得更快的程序 // edit: The first character must be an upper case letter, the next four must be // edit: numeric and there must be exactly five characters in total in a product
// edit: The first character must be an upper case letter, the next four must be
// edit: numeric and there must be exactly five characters in total in a product
// edit: code.
for (int i = 1; i < 5; i++)
if (codeInput.length() != 5 || codeInput.charAt(i) < '0'
|| codeInput.charAt(i) > '9' || codeInput.charAt(0) < 'A'
|| codeInput.charAt(0) > 'Z')
{if (verbose) System.out.println("Sorry, I don't understand!
Use product codes only."); return true;}
//编辑:第一个字符必须是大写字母,接下来的四个字符必须是
//编辑:数字,一个产品中总共必须有五个字符
//编辑:代码。
对于(int i=1;i<5;i++)
如果(codeInput.length()!=5 | | codeInput.charAt(i)<'0'
||codeInput.charAt(i)>'9'| | codeInput.charAt(0)<'A'
||codeInput.charAt(0)>“Z”)
{if(verbose)System.out.println(“对不起,我不明白!
仅使用产品代码。“);返回true;}
是,它将在每次迭代中计算codeInput.length()。如果codeInput
是最终的,或者一次只有一个线程可以访问,则编译器可能能够进行优化。否则,codeInput
可以被当前线程不会注意到的另一个线程更改
所以,程序员决定将codeInput.length()
转移到循环之外,并利用提高的性能。是的,它将在每次迭代中评估codeInput.length()
。如果codeInput
是最终的,或者一次只有一个线程可以访问,则编译器可能能够进行优化。否则,codeInput
可以被当前线程不会注意到的另一个线程更改
所以,程序员决定将codeInput.length()
转移到循环之外,并利用提高的性能;您应该尽可能地编写最简单、最清晰的代码,这样会执行得很好。通常情况下,性能问题的出现使得代码更加清晰更为重要。在你的例子中,我会这样写
static final Pattern CODE = Pattern.compile("[A-Z][0-9]{4}");
if (!CODE.matcher(codeInput).matches()) {
if (verbose)
System.out.println("Sorry, I don't understand! Use product codes only.");
return true;
}
即使这稍微慢一点,维护IMHO也更清晰、更容易
javac
几乎没有进行优化,它们几乎都是由JIT在运行时执行的
如果我用javac编译下面的代码,编译器是否足够聪明,可以只计算codeInput.length()一次
没有,但是,
或者,通过将受迭代器变量影响的求值放在第一位,我是否有可能获得更快的程序
// edit: The first character must be an upper case letter, the next four must be
// edit: numeric and there must be exactly five characters in total in a product
// edit: code.
for (int i = 1; i < 5; i++)
if (codeInput.length() != 5 || codeInput.charAt(i) < '0'
|| codeInput.charAt(i) > '9' || codeInput.charAt(0) < 'A'
|| codeInput.charAt(0) > 'Z')
{if (verbose) System.out.println("Sorry, I don't understand!
Use product codes only."); return true;}
它不像你会注意到的那样,如果代码运行的时间足够长,JIT就会启动,并且方法将被内联,这样就不需要局部变量;您应该尽可能地编写最简单、最清晰的代码,这样会执行得很好。通常情况下,性能问题的出现使得代码更加清晰更为重要。在你的例子中,我会这样写
static final Pattern CODE = Pattern.compile("[A-Z][0-9]{4}");
if (!CODE.matcher(codeInput).matches()) {
if (verbose)
System.out.println("Sorry, I don't understand! Use product codes only.");
return true;
}
即使这稍微慢一点,维护IMHO也更清晰、更容易
javac
几乎没有进行优化,它们几乎都是由JIT在运行时执行的
如果我用javac编译下面的代码,编译器是否足够聪明,可以只计算codeInput.length()一次
没有,但是,
或者,通过将受迭代器变量影响的求值放在第一位,我是否有可能获得更快的程序
// edit: The first character must be an upper case letter, the next four must be
// edit: numeric and there must be exactly five characters in total in a product
// edit: code.
for (int i = 1; i < 5; i++)
if (codeInput.length() != 5 || codeInput.charAt(i) < '0'
|| codeInput.charAt(i) > '9' || codeInput.charAt(0) < 'A'
|| codeInput.charAt(0) > 'Z')
{if (verbose) System.out.println("Sorry, I don't understand!
Use product codes only."); return true;}
这与您会注意到的区别不同,因为如果代码运行时间足够长,并且方法将内联,那么JIT将启动,从而消除对局部变量的需要。编译器必须创建计算codeInput.length()的代码
,因为它无法知道是否会在每次迭代中返回相同的值。你知道这是因为你知道这门课是如何运作的。但是编译器不知道它,并且必须假设codeInput
发生了变化(例如,由于调用charAt()
)
因此,是的:您可以通过计算codeInput.length()
一次并将结果分配给局部变量来获得一些性能。编译器必须在每次迭代时创建计算codeInput.length()
的代码,因为它无法知道是否在每次迭代时返回相同的值。你知道这是因为你知道这门课是如何运作的。但是编译器不知道它,并且必须假设codeInput
发生了变化(例如,由于调用charAt()
)
因此,是的:您可以通过计算codeInput.length()
一次并将结果分配给局部变量来获得一些性能。这里聪明的不是编译器,而是JVM
现代JVM都有JIT(即时),这意味着代码将在运行中得到优化
不要费心用Java优化代码,只需编写正确的代码即可。JVM将为您完成其余的工作
对于您的特定代码段,如果您正在使用,您可以在此处使用CharMatcher
以获得良好效果:
private static final CharMatcher PRODUCT_CHARS
= CharMatcher.inRange('A', 'Z')
.or(CharMatcher.inRange('a', 'z'))
.or(CharMatcher.inRange('0', '9'))
.precompute();
// In the verification method:
if (!(codeInput.length() == 5 && PRODUCT_CHARS.matchesAllOf(codeInput)))
badProductCode();
在这里,聪明的不是编译器,而是JVM
现代JVM都有JIT(即时),这意味着代码将在运行中得到优化
不要费心用Java优化代码,只需编写正确的代码即可。JVM将为您完成其余的工作
对于您的特定代码段,如果您正在使用,您可以在此处使用CharMatcher
以获得良好效果:
private static final CharMatcher PRODUCT_CHARS
= CharMatcher.inRange('A', 'Z')
.or(CharMatcher.inRange('a', 'z'))
.or(CharMatcher.inRange('0', '9'))
.precompute();
// In the verification method:
if (!(codeInput.length() == 5 && PRODUCT_CHARS.matchesAllOf(codeInput)))
badProductCode();
您的第一个目标应该是代码的简单性和可读性。对于像您所提出的问题这样简单的问题,您真的必须不遗余力地将其转化为性能瓶颈。最干净、最灵活的字符串验证方法是正则表达式:
boolean valid = codeInput.matches("[A-Z][0-9]{4}");
if (!valid && verbose)
System.out.println("Sorry, I don't understand! Use product codes only.");
return !valid;
如果您真的想从中获得最后一点性能,可以预编译正则表达式:
static final Pattern productCodeRegex = Pattern.compile("[A-Z][0-9]{4}");
boolean validate(String codeInput) {
boolean valid = productCodeRegex.matcher(codeInput).matches();
...
}
您的第一个目标应该是代码的简单性和可读性。对于像您所提出的问题这样简单的问题,您真的必须不遗余力地将其转化为性能瓶颈。最干净、最灵活的字符串验证方法是正则表达式:
boolean valid = codeInput.matches("[A-Z][0-9]{4}");
if (!valid && verbose)
System.out.println("Sorry, I don't understand! Use product codes only.");
return !valid;
如果你真的想要最后一点表现