Java:执行连接变量和文字的 StringBuilder.indexOf() 的开销

Min*_*ser 3 java string performance indexof

是否有执行的性能开销sb.indexOf(c + "") ,其中c是类型Character还是charsbStringBuilder对象?

Ami*_*nde 5

您可以使用 String.valueOf

builder.indexOf(String.valueOf(c));
Run Code Online (Sandbox Code Playgroud)

这种方法有一些好处。

  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
Run Code Online (Sandbox Code Playgroud)

如您所见,它创建了第二个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
Run Code Online (Sandbox Code Playgroud)

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

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

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

但同样,这可能是一个微观优化。该String.valueOf呼叫使代码更清晰,这是最主要的。

  • @ Amit:查看生成的字节码,我不得不同意。连接版本创建了第二个 `StringBuilder` 并执行了两个 `append` 调用,然后是一个 `toString`。`String.valueOf` 版本只调用 `String.valueOf`,它(查看源代码)创建您提到的单字符数组并调用 `String` 构造函数。只是感觉效率更高。并不是说它可能很重要,但仍然如此。 (3认同)