直到Java6,我们在String
上有一个常量时间子字符串。在Java7中,为什么他们决定复制char
数组——并降低线性时间复杂度——而像StringBuilder
这样的东西正是为此而准备的?
这将对后缀数组等数据结构的复杂性产生相当大的影响。Java应该提供一些替代方法来获取原始字符串的一部分。
如果你有一个长寿的短寿命的大父字符串的小子串,支持父字符串的大char[]将不符合垃圾回收机制,直到小子串移出范围。这意味着子串可以占用比人们预期的更多的内存。
Java 6方式的唯一一次表现明显更好的是,有人从一个大的父字符串中获取了一个大的子字符串,这是一种非常罕见的情况。
显然,他们认为这种变化的微小性能成本被旧方法带来的隐藏内存问题所抵消。决定性因素是问题被隐藏了,而不是有变通办法。
Oracle bug#4513622:(str)中讨论了他们决定的原因。保留字段的子字符串可以防止对象的GC:
当你调用字符串时。子字符串如示例中所示,未分配用于存储的新字符数组。它使用原始字符串的字符数组。因此,在子字符串的引用也可以被GC’d之前,支持原始字符串的字符数组不能被GC’d。这是一种有意的优化,以防止在常见情况下使用子字符串时分配过多。不幸的是,有问题的代码遇到了原始数组开销明显的情况。在两种情况下都很难进行优化。任何空间/大小权衡的优化通常都很复杂,而且往往是特定于平台的。
还有这个注释,注意到根据测试,曾经的优化已经变成了悲观:
很长一段时间以来,人们一直在准备和计划从java中删除偏移和计数字段。朗,弦。这两个字段允许多个字符串实例共享同一支持字符缓冲区。共享字符缓冲区对于旧的基准测试来说是一个重要的优化,但对于当前的真实代码和基准测试,实际上最好不要共享备份缓冲区。共享字符数组备份缓冲区仅“赢”,字符串使用非常频繁。子串。负面影响的情况可能包括解析器和编译器,但当前的测试表明,总体而言,这种变化是有益的。
问题内容: 在Java 6之前,我们在上有一个固定时间的子字符串。在Java 7中,为什么要使用复制数组并降级到线性时间复杂度? 问题答案: 在Oracle错误#4513622中讨论了为什么要做出决定:(str)保留字段的子字符串会阻止对象的GC: 如示例中那样调用String.substring时,未分配用于存储的新字符数组。它使用原始String的字符数组。因此,支持原始字符串的字符数组在子字
我得到了一个复杂的JSON字符串,如下所示。 这还不完整。但这怎么读呢?
我有一个逗号分层的字符串,当调用时,它返回大约60的数组大小。在特定的用例中,我只需要从数组中返回第二个值的值。例如,
假设我有一个字符串,如下所示: 我想把“abcd”换成“dddd”。我曾试图做这样的事: 它不起作用。有什么建议吗? 编辑:更具体地说,我在Java工作,我试图解析超文本标记语言文档,具体地说
我认为每次更改字符串后,Python字符串的id都必须更改。但我发现真正的行为是不同的。例如,并非输出下面的所有代码字符串都不同: 这就是为什么我认为Python内核正在尝试优化代码,并开始对内存中的字符串进行奇怪的操作。该假设的另一个论点是,常量ID与大小为2的幂的段相关联: 但这其中还有一件奇怪的事。让我们看看随着字符串大小的增加,段大小会发生什么变化: 最后,我们可以尝试近似地将char添加