性能(JAVA)〜循环中的字符串连接,带有前置和后置

9 java string performance loops concatenation

我遇到了性能问题.有没有人有更快/更好的解决方案来执行以下操作:

    String main = "";
    for (String proposition : propositions) {
        if (main.length() == 0) {
            main = proposition;
        } else {
            main = "|(" + proposition + "," + main + ")";
        }
    }
Run Code Online (Sandbox Code Playgroud)

我知道concat和stringbuilder更快,但我不知道如何使用这些方法.由于以下代码行:

main = "|(" + proposition + "," + main + ")";
Run Code Online (Sandbox Code Playgroud)

提前致谢!

Kis*_*kae 9

所以从我可以看出这里有3个问题:

  1. 值主要附加在字符串之前.
  2. 对于每个值,附加一个字符.
  3. 如果只存在一个值,则不应附加或预先添加任何值.
  4. 对于2个或更多项目,第0项处理方式不同:

0: ""

1: "A"

2: "|(B,A)"

3: "|(C,|(B,A))"

通过进行一些更改可以更快地完成:

  1. 反转算法,这意味着大部分工作都涉及追加,允许您使用StringBuilders.
  2. 计算结束次数)并在循环结束后附加那些.
  3. 列表中0或1项的特殊情况.

通过这些更改,算法应该能够使用StringBuilder并且更快.

尝试算法:

int length = propositions.size();
if (length == 0) {
    main = "";
} else {
    StringBuilder sb = new StringBuilder();
    int nestingDepth = 0;
    // Reverse loop, ignoring 0th element due to special case
    for (int i = length - 1; i > 0; i--) {
        sb.append("|(").append(propositions.get(i)).append(',');
        nestingDepth++;
    }
    // Append last element due to special casing
    sb.append(propositions.get(0));
    for (int i = 0; i < nestingDepth; i++) {
        sb.append(')');
    }

    main = sb.toString();
}
Run Code Online (Sandbox Code Playgroud)

相信这应该产生正确的结果,但它应该给出正确的想法.

  • @EJP插入需要移动所有先前的输入,它可能涉及与原始代码一样多的内存重排. (3认同)
  • 另一个选择是使用`ArrayDeque`,这是一个圆形结构,在开始时插入与结束一样快.最后你可以加入所有的字符串. (3认同)

Mic*_*son 7

问题是你正在前置并附加到字符串.String和StringBuilder不能很好地处理这个问题(并提供二次性能).但是您可以使用支持在开始和结束时插入的出列来存储所有部分.最后你可以加入出队的比特.

ArrayDeque bits = new ArrayDeque();
for (String proposition : propositions) {
    if (bits.size() == 0) {
        bits.push(proposition);
    } else {
        // Add prefix
        main.offerFirst("|(" + proposition + "," );
        // Add suffix
        main.push(")");
    }
}
StringBuilder sb = new StringBuilder();
for( String s : bits) {
   sb.append(s);
}
main = sb.toString();
Run Code Online (Sandbox Code Playgroud)