繁体   English   中英

在for循环中使用str.length()值之前将它存储在变量中是否会在Java中进行任何性能改进?

[英]Does storing the str.length() value in a variable before using it in a for loop have any performance improvements in Java?

简而言之,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()值来实现的吗?

我创建了以下两种方法,

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

很好的答案Elliot F.

我做了一个更简单的测试,并且运行了两个方法,重复次数非常多,并且每个方法都有时间。

第一种方法(其中长度仅计算一次)始终比第二种方法快。

这是我创建的整个测试类;

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM