为什么string.charAt(x)比string [x]慢得多

时间:2016-02-07 09:55:38

标签: java string

在Java中(对于其他语言也可能相同),用于访问字符串中字符的charAt(x)方法比访问char[]中的字符元素要慢得多。这对我来说没有多大意义,因为String使用char[]来表示数据。

这是我的测试和结果。

测试charAt()

for(int i = 1000000; i >= 0; i--){
    char c = s.charAt(5);
}

charAt()已用时间= 0.00261095

for(int i = 1000000; i >= 0; i--){
    char c = sArr[5];
}

arr[]已用时间0.001620297

来自String.Java

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

4 个答案:

答案 0 :(得分:2)

副手,我至少可以想到几个原因:

  1. charAt是方法调用

  2. 在Java 1.7.0_05 (感谢精确版本,Holger及以下,在charAt中,String确实可以确定基础char[]中的哪个条目可以提供给您,因为字符串可以共享char[]数组:

    if ((index < 0) || (index >= count)) {
        throw new StringIndexOutOfBoundsException(index);
    }
    return value[index + offset];
    

    offset是共享char[]中的偏移量。)

    在Java 1.7.0_06及更高版本中,它仍然会进行范围检查:

    if ((index < 0) || (index >= value.length)) {
        throw new StringIndexOutOfBoundsException(index);
    }
    return value[index];
    
  3. 因此,我们可以看到charAt执行您正在执行的操作(访问char[]条目),但必须具有方法调用的开销和范围检查(在Java 7及更早版本中,index + offset计算)。它可以帮助但速度有点慢。

    然后是possibility of measurement error,因为Java中的天真微基准测试往往存在问题。

答案 1 :(得分:1)

如果您查看source code of String,您会发现一旦调用该方法,就会对提供的索引进行两次检查。除此之外,一种方法在被调用时会自行消耗一些时间。这两个组合负责您注意到的时间延迟。

答案 2 :(得分:0)

因为charAt()是一个方法,它需要放在运行时堆栈上,每次调用时都需要更改控件,这需要一点时间。据我所知,他们都执行相同的操作。

答案 3 :(得分:0)

charAt()方法内部的错误检查实际上是对差异的考虑。我创建的测试并不“公平”,char[x]测试没有错误处理,所以时间更快

//来自charAt()的错误检查

if ((index < 0) || (index >= value.length)) {
    throw new StringIndexOutOfBoundsException(index);
}

使用以下

更新了arr[x]测试
    for(int i = 1000000; i >= 0; i--){
        if(dummy < 0 || dummy >= sArr.length) throw new IndexOutOfBoundsException();
        char c = sArr[5];
    }

更新时间:arr []已用时间0.002208887

现在更接近charAt(i)