【问题标题】:How to copy a String substring to a StringBuilder如何将字符串子字符串复制到 StringBuilder
【发布时间】:2020-03-14 19:47:45
【问题描述】:

将字符串子字符串复制到 StringBuilder 的最快方法是什么? 我试过了:

  • builder.append(string.substring(start, end)) 但它使用两个数组副本。
  • builder.append(string, start, end) 但它使用 for 循环而不是数组复制

遗憾的是StringBuilder#getValue 是私有包,所以我不能在String#getChars 中使用它。 此外,StringBuilder 是最终的,这意味着我无法更改 getValue 访问或添加将使用 String#getChars 而不是 for 循环的 append(str, start, end) 方法。

我想我错过了一些东西。我的意思是我不能成为第一个想要这个功能的人。

更新:

正如@Slaw 所说,StringBuilder#append(CharSequence, int, int) 在 9 到 13 之间更改为使用 arraycopy 而不是 for 循环。我很高兴这个“问题”得到了解决。

【问题讨论】:

  • 你为什么在乎?你有从 O(n) 到 O(n^2) 或类似的用例吗?
  • 也许实现已经从您正在查看的任何版本更改,但当前StringBuilder#append(CharSequence,int,int) 在第一个参数是Sting 的实例时尝试使用arraycopy。见github.com/openjdk/jdk/blob/master/src/java.base/share/classes/…
  • OpenJDK 8 中的@Slaw 真的很有趣,这是不同的
  • 我还是很好奇你为什么这么关心字符串缓冲区的性能。

标签: java performance java-8


【解决方案1】:

使用可以使用StringBuilder的构造函数

StringBuilder builder = new StringBuilder(string.substring(start, end));

【讨论】:

  • 感谢这是一个很好的解决方案。但是,在我的特殊情况下,这会破坏 StringBuilder 的目的。
  • 这与问题中已经显示的append(string.substring(start, end)) 有何不同?
【解决方案2】:

String 实现了CharSequence,因此您可以使用StringBuffer.append(CharSequence s,int start, int end),但是我要提醒您,除非您知道这可能是/是一个问题,否则使用此方法而不是substring 是过早的优化.

【讨论】:

  • 我在“认为我尝试过”中列出了这种方法。遗憾的是,它使用 for 循环而不是 arraycopy,因为 CharSequence 不提供 getChars()
  • @David 你怎么看,arraycopy 在内部做什么?
  • 公平地说,arraycopy 可能是矢量化/更快的,而根据我的经验,jvm 自动矢量化对于除了超简单循环之外的任何东西都是非常垃圾的(尽管我猜这算作一个超简单循环)。为什么@David 如此关心字符串缓冲区的性能,但对我来说仍然是个谜。
  • 我正在为一种非常不常见的文件类型编写解析器。在应用程序启动中,此文本的 1GB 被解析。我想也许我可以通过这种方式提高性能。
  • Arraycopy 应该更快,我的意思是它只复制引用,所以它可能只是复制内存部分,对吧?我现在不太关心 jvm natives 但我在 github 上看到一些大型项目仅在数组大于 8 时才使用 arraycopy,所以也许它并不总是更快。
猜你喜欢
  • 1970-01-01
  • 2010-10-29
  • 2014-08-03
  • 1970-01-01
  • 2015-04-29
  • 1970-01-01
  • 2010-09-09
  • 2020-06-18
相关资源
最近更新 更多