【问题标题】:In Java, is substring(int k, int y) or substring(int k) more efficient performance wise?在 Java 中,是 substring(int k, int y) 还是 substring(int k) 更高效?
【发布时间】:2012-11-19 03:06:57
【问题描述】:

例如,假设我有以下代码:

String s1 = "foobar";
s1 = s1.substring(3);

该代码的效率会低于:

String s1 = "foobar";
s1 = s1.substring(3, 6);

我在想双参数方法在性能方面会更有效,因为单参数方法使用循环来循环遍历索引,直到达到长度。这意味着JVM必须调用length()方法来找出何时停止循环。

但是两个参数的方法只循环到最后一个索引号。

谁能证实或否认我的假设?

编辑: 我不太了解源代码中的这段代码(最后一个返回语句),但这里是 java String 类源代码:

public String substring(int beginIndex, int endIndex) {
    if (beginIndex < 0) {
        throw new StringIndexOutOfBoundsException(beginIndex);
     }
     if (endIndex > count) {
        throw new StringIndexOutOfBoundsException(endIndex);
     }
    if (beginIndex > endIndex) {
    }
    return ((beginIndex == 0) && (endIndex == count)) ? this :    // I don't understand this part
         new String(offset + beginIndex, endIndex - beginIndex, value);
}

【问题讨论】:

  • 查看Strings.substring的源码
  • 您可以通过对两个版本进行基准测试自己确认或拒绝:)
  • 不要过早优化
  • @JanDvorak 我不是。这只是我坐在课堂上的一个想法,我知道不要做任何与过早优化有关的事情。
  • 在一个实际的例子中,为了避免调用 substring(3),你必须获取字符串的长度,然后调用 substring(3, s1.length()),这正是 substring(3) 所做的(但在更冗长,可读性更低的方式)。在您的示例中,最有效的版本是String s1 = "bar"

标签: java string performance jvm substring


【解决方案1】:

String.substring() 是常数时间1,它只是提供原始字符串的较小视图。此外,只有一个参数的版本……代表了一个有两个参数的版本:

public String substring(int beginIndex) {
    return substring(beginIndex, count);
}

其中countString.length() 返回的值。选择哪个版本并不重要,它们都非常快。

1 - 从 Java 7 更新 6 开始,显然是 no longer true。但这与您的问题无关。

【讨论】:

  • 这一天我已经投了足够多的票,否则我会给最后两个词+1。 ;)
  • 这在 Java 7 Update 6 中不再适用。现在总是复制支持 char[],使得这个 O(n)。
  • Here it is。请注意,substring 调用了公共构造函数 String(char[], int, int),当然,它会防御性地复制 char[]
  • 非常震撼。他们在赌博,因为它可能不会造成破坏。
  • @MarkoTopolnik 我没有意识到他们实际上已经完全删除了countoffset 字段。对子字符串的影响实际上是一个副作用。
【解决方案2】:

我认为没有任何区别。如果你看到 String 类源代码 substring(int beginIndex) -- 只需调用 substring(beginIndex, lengthOfTheString)

【讨论】:

    【解决方案3】:
     public String substring(int beginIndex, int endIndex) 
    

    稍微快一点,因为

     public String substring(int beginIndex) {
          return substring(beginIndex, count);
     }
    

    这样您就可以避免一种间接方式。但这不值得考虑。

    【讨论】:

      【解决方案4】:

      在java源码中,substring(beginIndex)会调用substring(beginIndex, count)

      【讨论】:

        猜你喜欢
        • 2021-11-11
        • 2015-06-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-20
        相关资源
        最近更新 更多