2017-08-30 37 views
1

我想多次使用字符串中的字符,并想知道每次使用string.charAt()是否更好我需要一个字符或保存字符数组与string.toCharArray()并使用索引来访问数组中的字符。所以我写了一个简单的基准程序,我观察到了显着的性能差异。更好的重复使用字符串中的字符在Java中

static int[] loops = new int[]{10000, 100000, 1000000}; 

static void useCharAt(String s){ 
    int sum = 0; 
    for(int loop : loops) { 
     long start = System.currentTimeMillis(); 
     for (int i = 0; i < loop; i++) { 
      for (int j = 0; j < s.length(); j++) { 
       sum += s.charAt(j); 
      } 
     } 
     System.out.println("string size is " + s.length() + ", loop size is "+loop+", charAt() costs " + (System.currentTimeMillis() - start) + " ms"); 
    } 
} 

static void useArray(String s){ 
    char[] arr= s.toCharArray(); 
    int sum = 0; 
    for(int loop : loops) { 
     long start = System.currentTimeMillis(); 
     for (int i = 0; i < loop; i++) { 
      for (char c : arr) { 
       sum += c; 
      } 
     } 
     System.out.println("string size is " + s.length() + ", loop size is "+loop+", array costs " + (System.currentTimeMillis() - start) + " ms"); 
    } 
} 

public static void main(String[] args){ 
    StringBuilder sb = new StringBuilder(); 
    int strLen[] = new int[]{1000, 5000, 10000}; 
    for(int len : strLen) { 
     sb.setLength(0); 
     for(int i = 0; i < len; i++) sb.append('a'); 
     String s = sb.toString(); 
     useArray(s); 
     useCharAt(s); 
    } 
} 

,其结果是

string size is 1000, loop size is 10000, array costs 10 ms 
string size is 1000, loop size is 100000, array costs 60 ms 
string size is 1000, loop size is 1000000, array costs 495 ms 
string size is 1000, loop size is 10000, charAt() costs 14 ms 
string size is 1000, loop size is 100000, charAt() costs 184 ms 
string size is 1000, loop size is 1000000, charAt() costs 1649 ms 

string size is 5000, loop size is 10000, array costs 23 ms 
string size is 5000, loop size is 100000, array costs 232 ms 
string size is 5000, loop size is 1000000, array costs 2277 ms 
string size is 5000, loop size is 10000, charAt() costs 82 ms 
string size is 5000, loop size is 100000, charAt() costs 828 ms 
string size is 5000, loop size is 1000000, charAt() costs 8202 ms 

string size is 10000, loop size is 10000, array costs 44 ms 
string size is 10000, loop size is 100000, array costs 458 ms 
string size is 10000, loop size is 1000000, array costs 4559 ms 
string size is 10000, loop size is 10000, charAt() costs 166 ms 
string size is 10000, loop size is 100000, charAt() costs 1626 ms 
string size is 10000, loop size is 1000000, charAt() costs 16280 ms 

我不知道为什么的charAt()是不是与数组直接访问慢?我检查了chatAt()的实现,我发现与数组直接访问方法没有区别。

public char charAt(int index) { 
    if ((index < 0) || (index >= value.length)) { 
     throw new StringIndexOutOfBoundsException(index); 
    } 
    return value[index]; 
} 
+1

函数调用费用+额外边界检查。一切看起来都很合理。 – algrid

+0

[我如何在Java中编写正确的微基准测试?](https://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java) –

+0

谢谢为你的评论!我浏览了一些文章和教程,并开始理解这个问题。 –

回答

2

使用toCharArray()带有初始成本,其中String的内部数组被复制。

从那时起,对数组的简单访问(在charAt()中发生隐式边界检查以及返回值时)。调用charAt()会带来函数调用的代价和重复的边界检查(抛出StringIndexOutOfBoundsException而不是ArrayIndexOutOfBoundsException)。

这种效果非常出名,早期的Java Performance书籍中已经提到过这种效果。

简而言之:如果只访问字符串中的单个字符,最好用charAt()。如果您访问更多或全部字符并且字符串可能更长,则最好使用toCharArray(),然后再遍历数组。

相关问题