【问题标题】:Append Strings - Performance issue - Java 6附加字符串 - 性能问题 - Java 6
【发布时间】:2015-04-27 09:36:06
【问题描述】:

我需要重复追加字符串(大约 50 次),这是另一个 StringBuilder 的子字符串。 我需要为大约 30k 输入执行此操作。 我需要大约 6 分钟的时间。

 StringBuilder input = new StringBuilder(10000);
    StringBuilder output = new StringBuilder(10000);

//for循环直到将字符串读入变量'input'的文件末尾

{
output.append(input.substring(1, 8));
output.append(input.substring(33, 45));
output.append(input.substring(20, 25)); // and so on
}

这大约需要 6 分钟。

所以,我尝试了类似的东西

{


 output.append(input.substring(1, 8) + output.append(input.substring(33, 45) + output.append(input.substring20, 25) + .. // and so on );

}

这,也花了同样的时间。我知道这两个是一样的。

但是,即使我使用了 StringBuilder,为什么我仍然有性能滞后?是不是我做错了什么?

我转介:StringBuilder vs String concatenation in toString() in JavaString concatenation in Java - when to use +, StringBuilder and concat 等等。 他们中的大多数人建议使用 StringBuilder。

【问题讨论】:

  • 我建议您在循环进行时监控 GC 活动。您可能会遇到内存限制。
  • "我知道这两个是一样的。"不,他们不是。您的第二个代码在每次迭代时将 output 转换为字符串,并使用字符串连接。你绝对不想那样做。
  • 也许这是您的问题:“for 循环直到将字符串读入变量 'input' 的文件末尾”?向我们展示您如何设置阅读器以及您的阅读方式。
  • 追加 50 个小子串,50K 次是不可能花费比几秒钟多得多的。如果花费的时间更长,则更有可能在您未提及的地方工作。我建议你分析你的应用程序。
  • @Seelenvirtuose :实际上我是从队列中读取它们的……不是从文件中读取的……所以,我一直读取到队列大小为零。

标签: java string performance append stringbuilder


【解决方案1】:

性能问题很可能出在其他地方,因为这不会超过一秒钟。我建议您分析您的应用程序以确定它实际花费的处理时间。

long start = System.currentTimeMillis();
char[] chars = new char[500];
Arrays.fill(chars, '.');
for (int i = 0; i < 30000; i++) {
    String input = new String(chars);
    StringBuilder output = new StringBuilder();
    for (int j = 0; j < 50; j++) {
        output.append(input, j * 10, j * 10 + 9);
    }
    String out = output.toString();
}
System.out.println("Took: " + (System.currentTimeMillis() - start) / 1e3 + " seconds");

打印 30,000 个字符串的 50 个子字符串

Took: 0.058 seconds

【讨论】:

    【解决方案2】:

    你绝对可以避免使用append的重载来创建这么多对象,它允许你指定一个子序列:

    for (...)
    {
        output.append(input, 1, 8);
        output.append(input, 33, 45);
        output.append(input, 20, 25);
    }
    

    这可能会或可能不会帮助您。绝对应该避免第二个示例中的字符串连接 - 我很惊讶这并没有产生 巨大的 差异......这表明它可能不是花费时间的附加,但无论如何读取输入。

    要对此进行测试,您可能应该尝试 empty for 循环,这样您仍然可以读取所有相同的输入,但根本不会附加到 output

    【讨论】:

    • 短期字符串只会增加次要 GC 频率。这是问题的可能性非常小,特别是考虑到单个子字符串的大小。
    • @MarkoTopolnik:同意。基本上我们真的不知道时间在哪里 - 因此我建议只循环输入。
    猜你喜欢
    • 2016-06-11
    • 1970-01-01
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    • 2014-06-21
    • 2017-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多