Java String.format 和 StringBuilder 之间的性能

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44117788/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 01:21:11  来源:igfitidea点击:

Performance between String.format and StringBuilder

javastringbuilderstring.format

提问by JUAN CALVOPINA M

To concatenate Stringwe often use StringBuilderinstead of String+ String, but also we can do the same with String.formatwhich returns the formatted string by given locale, format and arguments.

为了连接,String我们经常使用StringBuilder而不是String+ String,但我们也可以使用String.format它返回给定语言环境、格式和参数的格式化字符串。

Examples:

例子:

Concatenate the string with StringBuilder

用 StringBuilder 连接字符串

String concatenateStringWithStringBuilder(String name, String lName, String nick) {
    final StringBuilder sb = new StringBuilder("Contact {");
    sb.append(", name='").append(name)
      .append(", lastName='").append(lName)
      .append(", nickName='").append(nick)
      .append('}');
    return sb.toString();
}

Concatenate the string with StringFormat:

用 StringFormat 连接字符串:

String concatenateStringWithStringFormat(String name, String lName, String nick) {
    return String.format("Contact {name=%s, lastName=%s, nickName=%s}", name, lName, nick);
}

In performance, is String.Formatas efficient as StringBuilder? Which one is better to concatenate strings and why?

在性能上,String.FormatStringBuilder? 哪个更适合连接字符串,为什么?

UPDATE

更新

I checked the similar question, but doesn′t answer my question. So far I have used StringBuilderto concatenate strings, should I follow it using? Or should I use String.format? the question is which one is better and why?

我检查了类似的问题,但没有回答我的问题。到目前为止,我已经习惯StringBuilder连接字符串,我应该使用它吗?还是我应该使用String.format?问题是哪个更好,为什么?

采纳答案by JUAN CALVOPINA M

After doing a little test with StringBuildervs String.formatI understood how much time it takes each of them to solve the concatenation. Here the snippet code and the results

在用StringBuildervs做了一个小测试后,String.format我明白了他们每个人解决串联需要多少时间。这里是代码片段和结果

Code:

代码:

String name = "stackover";
String lName = " flow";
String nick = " stackoverflow";
String email = "[email protected]";
int phone = 123123123;

//for (int i = 0; i < 10; i++) {
long initialTime1 = System.currentTimeMillis();
String response = String.format(" - Contact {name=%s, lastName=%s, nickName=%s, email=%s, phone=%d}",
                                name, lName, nick, email, phone);
long finalTime1 = System.currentTimeMillis();
long totalTime1 = finalTime1 - initialTime1;
System.out.println(totalTime1 + response);

long initialTime2 = System.currentTimeMillis();
final StringBuilder sb = new StringBuilder(" - Contact {");
sb.append("name=").append(name)
  .append(", lastName=").append(lName)
  .append(", nickName=").append(nick)
  .append(", email=").append(email)
  .append(", phone=").append(phone)
  .append('}');
String response2 = sb.toString();
long finalTime2 = System.currentTimeMillis();
long totalTime2 = finalTime2 - initialTime2;
System.out.println(totalTime2 + response2);
//}

After of run the code several times, I saw that String.formattakes more time:

多次运行代码后,我看到这String.format需要更多时间:

String.format: 46: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
StringBuilder: 0: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
String.format: 38: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
StringBuilder: 0: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
String.format: 51: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
StringBuilder: 0: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}

But if I run the same code inside a loop, the result change.

但是如果我在循环中运行相同的代码,结果就会改变。

String.format: 43: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
StringBuilder: 0: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
String.format: 1: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
StringBuilder: 0: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
String.format: 1: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
StringBuilder: 0: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}

The first time String.formatruns it takes more time, after of that the time is shorter even though it does not become constant as a result of StringBuilder

第一次String.format运行需要更多时间,之后时间更短,即使由于以下原因它不会变得恒定StringBuilder

As @G.Fiedler said: "String.formathas to parse the format string..."

正如@G.Fiedler 所说:“String.format必须解析格式字符串......”

With these results it can be said that StringBuilderis more efficient thanString.format

有了这些结果,可以说StringBuilderString.format

回答by G. Fiedler

StringBuilderis faster, because String.formathas to parse the format string (a complex domain specific language). And that's expensive.

StringBuilder更快,因为String.format必须解析格式字符串(一种复杂的领域特定语言)。那很贵。

StringBuilder instead of String + String

StringBuilder 而不是 String + String

BTW: It's the same, because it results in the same byte code (since Java 1.5).

顺便说一句:它是一样的,因为它产生相同的字节码(从 Java 1.5 开始)。

回答by Svetlin Zarev

What is "better" solely depends on your requirements:

什么是“更好”完全取决于您的要求:

  • For instance String Builderwill be faster, but the code will be much more unreadable, and and it would be easier to make a mistake.

  • On the other hand String.format()produces more readable code at the cost of performance.

  • 例如String Builder会更快,但代码将更加不可读,并且更容易出错。

  • 另一方面String.format(),以牺牲性能为代价生成更易读的代码。

JMH benchmark to illustrate the performance difference (notice that the string builder code is longer and very hard to understand how the resulting string would look like):

JMH 基准测试来说明性能差异(请注意,字符串生成器代码较长并且很难理解结果字符串的外观):

@Fork(1)
@State(Scope.Benchmark)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Measurement(iterations = 10)
@Warmup(iterations = 10)
@BenchmarkMode(Mode.Throughput)
public class StringFormatBenchmark {
    private String name = "UserName";
    private String lName = "LUserName";
    private String nick = "UserNick";

    @Benchmark
    public void stringFormat(Blackhole blackhole) {
        final String result = String.format("Contact {name=%s, lastName=%s, nickName=%s}", name, lName, nick);
        blackhole.consume(result);
    }

    @Benchmark
    public void stringBuilder(Blackhole blackhole) {
        final StringBuffer sb = new StringBuffer("Contact {");
        sb.append(", name='").append(name)
                .append(", lastName='").append(lName)
                .append(", nickName='").append(nick)
                .append('}');
        final String result = sb.toString();
        blackhole.consume(result);
    }
}

And the results:

结果:

Benchmark                             Mode  Cnt      Score     Error   Units
StringFormatBenchmark.stringBuilder  thrpt   10  10617.210 ± 157.302  ops/ms
StringFormatBenchmark.stringFormat   thrpt   10    960.658 ±   7.398  ops/ms

For non performance critical code I prefer using the String.format(), because it's easier and more pleasant to use. Also it's visible what the resulting string would look like, by simply looking at the pattern. If I'm doing a performance critical code, or something that has to have a low GC impact, I would use a StringBuilderbecause it's faster and can be reused.

对于非性能关键代码,我更喜欢使用String.format(),因为它使用起来更容易也更愉快。此外,通过简单地查看模式,结果字符串的外观也是可见的。如果我正在编写性能关键代码,或者必须具有低 GC 影响的代码,我会使用 a,StringBuilder因为它更快并且可以重用。