1

我正在努力提高我的应用程序的性能。我对以下哪个会使用更多内存感到困惑:这里 sb 是StringBuffer

String strWithLink = sb.toString();
clickHereTextview.setText(
     Html.fromHtml(strWithLink.substring(0,strWithLink.indexOf("+"))));

或者

clickHereTextview.setText(
     Html.fromHtml(sb.toString().substring(0,sb.toString().indexOf("+"))));
4

6 回答 6

3

记忆方面,一个表达式如

sb.toString().indexOf("+")

几乎没有影响,因为字符串将在评估后立即被垃圾收集。(为了避免临时内存使用,我建议这样做

sb.indexOf("+")

相反。)

但是,您使用String.substring. 上次我检查了substring基本上返回原始字符串的视图,所以原始字符串仍然驻留在内存中。

解决方法是做

String strWithLink = sb.toString();
... new String(strWithLink.substring(0,strWithLink.indexOf("+"))) ...
    ^^^^^^^^^^

从原始(可能很大)字符串中分离想要的字符串。同样适用于String.split此处讨论的内容:

于 2012-06-13T08:32:18.500 回答
2

第二种会使用更多内存,因为每次调用StringBuilder#toString()都会创建一个新的 String 实例。

http://www.docjar.com/html/api/java/lang/StringBuilder.java.html

于 2012-06-13T08:31:22.667 回答
2

分析

如果我们查看StringBuilder 的 OpenJDK 源代码

public String toString() {
    // Create a copy, don't share the array
    return new String(value, 0, count);
}

我们看到,它实例化了一个全新的 String 对象。它将与调用 sb.toString() 的次数一样多的新实例放入字符串池中。

结果

使用String strWithLink = sb.toString();,重用它将从池中检索相同的 String 实例,而不是新的实例。

于 2012-06-13T08:33:59.297 回答
1

创建新对象总是占用更多内存。但是,在您的情况下,差异似乎微不足道。

此外,在您的情况下,您正在创建一个占用堆空间的局部变量。

每当在您的方法中的多个位置有引用时,最好使用它 String strWithLink = sb.toString();,因为您可以在strWithLink任何地方使用相同的。否则,如果只有一个引用,sb.toString();直接使用总是更好。


于 2012-06-13T08:31:14.447 回答
1

检查其他人的答案,第二个确实需要更多的内存,但这听起来像是您过度优化了。保持代码清晰易读应该是首要任务。如果可读性会受到影响,我建议你不要太担心这种微小的优化。

于 2012-06-13T08:33:46.893 回答
1

你做的工作越少,通常效率就越高。在这种情况下,您根本不需要调用 toString

clickHereTextview.setText(Html.fromHtml(sb.substring(0, sb.indexOf("+"))));
于 2012-06-13T08:36:43.557 回答