【问题标题】:Better way to repeatedly use characters from a string in Java在 Java 中重复使用字符串中的字符的更好方法
【发布时间】:2017-08-30 20:54:13
【问题描述】:

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

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];
}

【问题讨论】:

标签: java string performance


【解决方案1】:

使用 toCharArray() 在复制字符串的内部数组时会产生初始成本。

从那时起,它就是对数组的简单访问(在 charAt() 中以及在返回值时进行隐式边界检查)。 charAt() 的调用伴随着函数调用和重复边界检查(抛出 StringIndexOutOfBoundsException 而不是 ArrayIndexOutOfBoundsException)的成本。

这种效果是众所周知的,在早期的 Java 性能书籍中已经提到过。

简而言之:如果您只访问字符串中的单个字符,最好使用 charAt()。如果您访问更多或所有字符并且字符串可能更长,则最好使用 toCharArray() 并通过数组来代替。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-14
    • 2013-08-12
    • 1970-01-01
    • 1970-01-01
    • 2016-05-13
    • 2020-01-22
    • 1970-01-01
    • 2011-10-22
    相关资源
    最近更新 更多