3

sb.indexOf(c + "") 执行where cis of typeCharactercharand sbis StringBuilderobject是否有性能开销?

4

2 回答 2

5

您可以使用String.valueOf

builder.indexOf(String.valueOf(c));

这种方法有很多好处。

  1. 干净的代码
  2. String.valueOf 使用 char[] 从传递的 char 创建 String 对象,char data[] = {c};因此不需要额外的操作。

2真的是一个微优化,我总是会选择1“干净的代码”这个选项。

值得一提的是,这是连接版本生成的字节码:

new #2; //class java/lang/StringBuilder
dup
invokespecial #6; //Method java/lang/StringBuilder."<init>":()V
aload_1
invokevirtual #7; //Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
ldc #8; //String 
invokevirtual #9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
invokevirtual #10; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
invokevirtual #11; //Method java/lang/StringBuilder.indexOf:(Ljava/lang/String;)I

如您所见,它创建了第二个StringBuilder,进行了两次append调用,然后是一个toString. 相比之下,这是String.valueOf版本:

aload_0
aload_1
invokestatic #12; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
invokevirtual #11; //Method java/lang/StringBuilder.indexOf:(Ljava/lang/String;)I

这只是将Character(已经自动拆箱成 a char)交给String.valueOf. 那有什么作用呢?我们看一下JDK源码:

public static String valueOf(char c) {
    char data[] = {c};
    return new String(0, 1, data);
}

所以它创建了一个新的单字符数组并直接交给String构造函数。很有可能效率更高。

但同样,这可能是一个微优化。String.valueOf调用使代码更清晰,这是主要的。

于 2012-10-21T07:39:30.733 回答
0

Java中的StringStringBuilder/StringBuffer类使用模式优先精确字符串匹配算法的蛮力方法。该算法涉及在文本的所有位置检查模式的出现,该模式从某个位置开始并移动一个位置,因此我感觉String.indexOf并且StringBuilder.indexOf在性能方面将是相同的。

但是,String该类有一个indexOf(char c)方法,而StringBuilder/StringBufferindexOf(String s)方法,所以如果您在其中搜索一个字符,StringBuilder您必须首先将 char 转换为 String。在您的示例中,这可能是唯一的开销。

注意:String 和 StringBuilder 类使用的蛮力算法在处理中小型文本时就足够了,但在处理大型文档时,最好使用更复杂的搜索字符串搜索算法。

于 2012-10-21T08:10:14.780 回答