简而言之,JVM是否在内部优化了以下代码
public void test(String str)
{
int a = 0;
for( int i = 0; i < 10; i++)
{
a = a + str.length();
}
}
表现得与以下效率一样高效:
public void test(String str)
{
int len = str.length();
int a = 0;
for( int i = 0; i < 10; i++)
{
a = a + len;
}
}
如果它确实优化了,它是通过内部缓存str.length()值来实现的吗?
答案 0 :(得分:6)
我创建了以下两种方法,
public void test(String str) {
int len = str.length();
int a = 0;
for (int i = 0; i < 10; i++) {
a = a + len;
}
}
public void test2(String str) {
int a = 0;
for (int i = 0; i < 10; i++) {
a = a + str.length();
}
}
然后我使用javap -v
生成第一个方法test
public void test(java.lang.String);
descriptor: (Ljava/lang/String;)V
flags: ACC_PUBLIC
Code:
stack=2, locals=5, args_size=2
0: aload_1
1: invokevirtual #16 // Method java/lang/String.length:()I
4: istore_2
5: iconst_0
6: istore_3
7: iconst_0
8: istore 4
10: goto 20
13: iload_3
14: iload_2
15: iadd
16: istore_3
17: iinc 4, 1
20: iload 4
22: bipush 10
24: if_icmplt 13
27: return
和test2
public void test2(java.lang.String);
descriptor: (Ljava/lang/String;)V
flags: ACC_PUBLIC
Code:
stack=2, locals=4, args_size=2
0: iconst_0
1: istore_2
2: iconst_0
3: istore_3
4: goto 17
7: iload_2
8: aload_1
9: invokevirtual #16 // Method java/lang/String.length:()I
12: iadd
13: istore_2
14: iinc 3, 1
17: iload_3
18: bipush 10
20: if_icmplt 7
23: return
所以答案似乎是存储长度一次有一些优势(它产生更短的字节码,相当于23对27行),这似乎暗示可能表现更好,但我怀疑它实际上可以衡量。特别是在代码被JIT编译之后)。
最后,您可以考虑
public void test(String str)
{
int a = 0;
for( int i = 0, len = str.length(); i < 10; i++) {
a = a + len;
}
}
或只是
int a = 10 * str.length();
答案 1 :(得分:6)
我做了一个更简单的测试,并且运行了两个方法,重复次数非常多,并且每个方法都有时间。
第一种方法(其中长度仅计算一次)始终比第二种方法快。
这是我创建的整个测试课程;
package _testing;
import java.util.Date;
public class Speed {
long count = 5000000;
public static void main(String[] args) {
long start, finish;
Speed sp = new Speed();
start = new Date().getTime();
sp.test("test");
finish = new Date().getTime();
System.out.println("test 1:"+(finish - start));
start = new Date().getTime();
sp.test2("test");
finish = new Date().getTime();
System.out.println("test 2:"+(finish - start));
}
public void test(String str) {
int len = str.length();
int a = 0;
for (int i = 0; i < count; i++) {
a = a + len;
}
}
public void test2(String str) {
int a = 0;
for (int i = 0; i < count; i++) {
a = a + str.length();
}
}
}
输出看起来像这样;
test 1:7
test 2:22