【问题标题】:How does the performance of String.substring() compare with manual lookups into a copied char[] array?与手动查找复制的 char[] 数组相比,String.substring() 的性能如何?
【发布时间】:2015-10-25 18:37:58
【问题描述】:

我正在研究一个连续扫描大量相对较短的字符串并从中生成大量子字符串的函数。该函数将用于大容量字符串处理系统。我更喜欢首先优化内存,其次是 CPU,因为我遇到的内存比系统上的 CPU 压力更大。在这种情况下,性能如何比较:

//Java-ish PseudoCode
functionParent(List<String> strings) {
  StringBuilder result;
  for(String s : strings) {
    result.appendAll(functionA(s));
  }
}


functionA(String arg1) {
  results.add(arg1.substring(i, i + length)); //hotspot here
}

和:

//Java-ish PseudoCode
functionParent(List<String> strings) {
  StringBuilder result;
  for(String s : strings) {
    result.appendAll(functionB(s.toCharArray()));
  }
}

functionB(char[] arg1) {
  results.add(new String(arg1,i, length)); //hotspot here
}

据我目前的测试所知,内存方面它是一个清洗(char[] 分配可以忽略不计,不会影响 GC,两者都创建相同数量的新字符串/substring() 内存-leak 已在不久前修复),并且 CPU 明智的 char[] 版本获胜,因为不断查找子字符串。这听起来正确吗?我在分析中遗漏了什么吗?


解决方案说明 根据下面的答案,functionB 似乎是最快的。另请注意,functionParent 中有一个 StringBuilder - 并且 StringBuilder 有一个 1append(char[], index, length)` 函数

【问题讨论】:

    标签: string performance java-7


    【解决方案1】:

    String.substring - 除了边界检查,通过调用 new String(value, beginIndex, subLen) 完成 - 除非结果是整个原始字符串,在这种情况下它只返回原始字符串。

    所以我会使用你的第二个/“functionB”示例。

    【讨论】:

    • 这是对上述toCharArray 测试的重复
    • @blueberryfields ? - 这个不用String.toCharArray(),也不用String.substring。
    • (我猜您正在查看子字符串的源代码,并没有注意到您给出的引用是使用内部字符数组,而不是字符串)。你已经说服我 toCharArray 转换是值得的,因为它节省的边界检查比它在 memcopy 中的成本要多,并且有 0 gc 后果
    • 给我展示一个 new String(arg1,i, length) 的实现
    • 我以为我们在谈论“Java-ish PseudoCode”。 :-) 更新答案以反映。
    【解决方案2】:

    如果您在使用包含大量 substring 和 append 类似操作的 String 操作时遇到内存压力,您应该注意 CharSequence 抽象。许多 API 已经准备好使用这些来代替 String。

    由于String 本身实现了CharSequence,因此您可以将方法更改为接受CharSequence 输入而不是String,而不会改变它们的用处。 subSequence 实现 String 将与 substring 执行相同的操作,因此复制内容,但您可以使用 CharBuffer.wrap(string, start, end) 创建不复制的子序列。

    如前所述,大多数操作都支持CharSequence 输入,尤其是您的用例

    请注意,StringBuilder 也实现了 CharSequence,因此允许您的操作往返,而无需创建中间的 String 副本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-15
      • 2016-02-26
      • 2011-03-22
      • 2011-12-25
      • 2020-11-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多