【问题标题】:Avoid String charAt() method inside loops避免在循环中使用 String charAt() 方法
【发布时间】:2015-06-07 05:42:45
【问题描述】:

如果我替换,对代码优化(速度等)有什么影响吗?

//之前

public void test(String str)  
{
     for(int i=0; i<str.length(); i++)
     {      
          System.out.println(str.charAt(i)); // VIOLATION 
     }
}

上面的代码片段和下面的代码:-

// 之后

public void test(String str)
{      
     char[] ch = str.toCharArray(); // CORRECTION
     for(int i=0; i < ch.length; i++) 
     {             
          System.out.println(ch[i]); // CORRECTION    
     }
}

【问题讨论】:

  • 真的是回答“X 比 Y 快吗?”的唯一方法。是试试看。
  • 当您遇到瓶颈并将其定位到特定代码位时,最好进行优化。您是否发现这段代码是导致您的应用程序运行缓慢的原因?
  • toCharArray 必须遍历整个字符串并创建数组,该数组将首先复制所有字符。然后,您将不得不再次迭代该副本。 charAt 没有这个问题。
  • @Pshemo :-) 另一方面,System.out.println(ch[i]); 可能在某些机器上运行得更快,因为它可以直接访问数组索引(JIT 可能会很好地优化它)。如果是 @ 987654327@ 每次调用时都会进行额外的条件检查,这可能会导致 JIT 无法优化代码。 :)
  • @TheLostMind 是的,这就是为什么我们通常不会去优化,直到我们看到某些功能真的很慢:) 正如已经说过的“Premature optimization is the root of all evil

标签: java string for-loop


【解决方案1】:

是的。你仍然可以优化。

public void test(String str)
{      
     char[] ch = str.toCharArray(); // CORRECTION
     int n = ch.length;
     for(int i=0; i < n; i++) 
     {             
           System.out.println(ch[i]); // CORRECTION    
     }
}

【讨论】:

  • 不是 Down 投票者.. 但数组的长度将在编译期间知道.. 编译器将进行比您已经完成的更准确(甚至更好)的更正.. 这将不影响运行时性能
  • 我不能同意,如果 str 作为参数传递,在编译时如何知道它?
【解决方案2】:

我认为您不会看到任何明显的差异。即使你这样做,我相信它也会因平台而异。

 for(int i=0; i<str.length(); i++) 

将由编译器更改为:

int strLength = str.length();
 for(int i=0; i<strLength ; i++)

因此,您不会每次都在循环内计算长度。

我认为第二种情况会稍微快一点(我可能是错的),因为数组访问速度更快并且可以很容易地被编译器优化。字节码形式的charAt() 也访问相同的数组,但有额外的指令来检查StringIndexOutOfBoundsExceptionif 内的两个条件检查)。

正如 Pshemo 所说 -toCharArray 将必须遍历整个字符串并创建数组,该数组将首先复制所有字符。然后,您将不得不再次迭代该副本。 charAt 没有这个问题

因此,总体而言,答案可能因架构而异。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-27
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-28
    • 2017-09-15
    • 2014-12-02
    相关资源
    最近更新 更多