偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Java中八種字符串拼接方式,性能很意外

開(kāi)發(fā) 前端
StringBuffer?提供了一個(gè)可變的字符序列。它允許對(duì)字符串進(jìn)行動(dòng)態(tài)操作而無(wú)需創(chuàng)建新的對(duì)象。值得一提的是,它被設(shè)計(jì)為線(xiàn)程安全的,這意味著它可以被多個(gè)線(xiàn)程安全地并發(fā)訪(fǎng)問(wèn)和修改。

環(huán)境:SpringBoot3.2.5

1. 簡(jiǎn)介

在開(kāi)發(fā)中,字符串拼接是非常常見(jiàn)的操作,廣泛應(yīng)用于日志記錄、數(shù)據(jù)處理、用戶(hù)界面生成等場(chǎng)景。然而,不同的字符串拼接方式在性能上有著顯著的差異,這一點(diǎn)往往被開(kāi)發(fā)人員忽視。本文將詳細(xì)介紹 Java 中的 8 種字符串拼接方式,并通過(guò)性能測(cè)試揭示這些方法的實(shí)際表現(xiàn),結(jié)果令人意外。

Java中可以使用如下8種方式進(jìn)行字符串的拼接:

  1. "+"操作符
  2. String#concat方法
  3. String#join方法
  4. String#format方法
  5. Stream流方式
  6. StringBuffer
  7. StringBuilder
  8. StringJoiner

下面我們依次介紹這8中方式;接下來(lái)的示例我們都將建立在JMH之上。

2. 實(shí)戰(zhàn)案例

2.1 "+"操作符

這是最簡(jiǎn)單的方法,也是我們可能最熟悉的一種。它可以使用加號(hào)(+)運(yùn)算符來(lái)連接字符串字面量、變量或者二者的組合:

@Benchmark
public void plusOperator(Blackhole hole) {
  String str1 = "Pack";
  String str2 = " xxxooo";
  String result = str1 + str2;
  hole.consume(result);
}

2.2 String#concat方法

concat() 方法由 String 類(lèi)提供,可用于將兩個(gè)字符串連接在一起。

@Benchmark
public void concat(Blackhole hole) {
  String str1 = "Pack";
  String str2 = " xxxooo";
  String result = str1.concat(str2);
  hole.consume(result);
}

2.3 String#join方法

String.join() 是 Java 8 以后新增的靜態(tài)方法。它允許使用指定的分隔符連接多個(gè)字符串。

@Benchmark
public void join(Blackhole hole) {
  String str1 = "Pack"; 
  String str2 = " xxxooo"; 
  String result = String.join("", str1, str2);
  hole.consume(result);
}

2.4 String#format方法

String.format() 用于使用占位符和格式指定符格式化字符串。通過(guò)使用實(shí)際值替換占位符,可以創(chuàng)建格式化字符串。

@Benchmark
public void format(Blackhole hole) {
  String str1 = "Pack"; 
  String str2 = " xxxooo"; 
  String result = String.format("%s%s", str1, str2);
  hole.consume(result);
}

2.5 Stream流

它為在對(duì)象集合上執(zhí)行操作提供了一種富有表現(xiàn)力的方法,并允許我們使用 Collectors.joining() 來(lái)集中字符串。

@Benchmark
public void stream(Blackhole hole) {
  List<String> strList = Arrays.asList("Pack", " xxxooo");
  String result = strList.stream().collect(Collectors.joining());
  hole.consume(result);
}

2.6 StringBuffer

StringBuffer 提供了一個(gè)可變的字符序列。它允許對(duì)字符串進(jìn)行動(dòng)態(tài)操作而無(wú)需創(chuàng)建新的對(duì)象。值得一提的是,它被設(shè)計(jì)為線(xiàn)程安全的,這意味著它可以被多個(gè)線(xiàn)程安全地并發(fā)訪(fǎng)問(wèn)和修改。

@Benchmark
public void stringBuffer(Blackhole hole) {
  StringBuffer buffer = new StringBuffer();
  buffer.append("Pack") ; 
  buffer.append(" xxxooo") ; 
  String result = buffer.toString() ;
  hole.consume(result) ;
}

2.7 StringBuilder

StringBuilder 和 StringBuffer 的用途相同。它們之間唯一的區(qū)別是 StringBuilder 不是線(xiàn)程安全的,而 StringBuffer 是。在不需要考慮線(xiàn)程安全的單線(xiàn)程場(chǎng)景中,StringBuilder 是非常完美的選擇。

@Benchmark
public void stringBuilder(Blackhole hole) {
  StringBuilder builder = new StringBuilder() ; 
  builder.append("Pack") ; 
  builder.append(" xxxooo") ; 
  String result = builder.toString() ;
  hole.consume(result) ;
}

2.8 StringJoiner

StringJoiner 是從 Java 8 開(kāi)始引入的一個(gè)新類(lèi)。它的功能與 StringBuilder 類(lèi)似,提供了一種使用分隔符連接多個(gè)字符串的方式。盡管它與 StringBuilder 有相似之處,但 StringJoiner 也不是線(xiàn)程安全的。

@Benchmark
public void stringJoiner(Blackhole hole) {
  StringJoiner joiner = new StringJoiner("");
  joiner.add("Pack") ;
  joiner.add(" xxxooo") ;
  String result = joiner.toString() ;
  hole.consume(result) ;
}

以上我們簡(jiǎn)單的介紹了每一種字符串拼接的使用。

3. 性能測(cè)試

接下來(lái),我們通過(guò)JMH進(jìn)行性能的測(cè)試,首先我們?cè)陬?lèi)上添加如下的注解:

// 預(yù)熱1s鐘,預(yù)熱3次
@Warmup(iterations = 3, time = 1)
// 啟動(dòng)多少個(gè)進(jìn)程
@Fork(value = 1, jvmArgsAppend = {"-Xms512m", "-Xmx512m"})
// 指定顯示結(jié)果(枚舉值)
@BenchmarkMode(Mode.AverageTime)
// 指定顯示結(jié)果單位(枚舉值)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
// 迭代10次,每次2s
@Measurement(iterations = 10, time = 2, timeUnit = TimeUnit.SECONDS)
public class StringJoinTest {
  // 上面8種字符串拼接的方法
}

在本示例中,我們將通過(guò)main的方式運(yùn)行,這種方式稍微有點(diǎn)不是特別準(zhǔn)確,你可以選擇jar的方式。

public static void main(String[] args) throws Exception {
  Options options = new OptionsBuilder()
    // 你要測(cè)試的類(lèi)
    .include(StringJoinTest.class.getSimpleName())
    // 啟動(dòng)幾個(gè)進(jìn)程
    .forks(1).build();
  new Runner(options).run();
}

最終測(cè)試結(jié)果如下:

圖片圖片

下面是對(duì)上面每一列的說(shuō)明(以第一行concat測(cè)試為例說(shuō)明)

Benchmark

a.說(shuō)明:基準(zhǔn)測(cè)試的名稱(chēng),通常是類(lèi)名+方法名。

b.示例:StringJoinTest.concat。

Mode

a.說(shuō)明:基準(zhǔn)測(cè)試的模式,常見(jiàn)模式有:

  • avgt:平均時(shí)間模式(Average Time),每個(gè)操作的平均時(shí)間。
  • thrpt:吞吐量模式(Throughput),單位時(shí)間內(nèi)完成的操作次數(shù)。
  • sample:采樣模式,用于收集詳細(xì)的統(tǒng)計(jì)信息。
  • ss:穩(wěn)定狀態(tài)模式,用于評(píng)估長(zhǎng)時(shí)間運(yùn)行的性能穩(wěn)定性。

  b.示例:avgt

Cnt

  • 說(shuō)明:迭代次數(shù),即基準(zhǔn)測(cè)試運(yùn)行的次數(shù)。
  • 示例:10

Score

a.說(shuō)明:基準(zhǔn)測(cè)試的主要結(jié)果指標(biāo)。根據(jù)模式的不同,這個(gè)值的含義也不同。

  • avgt:每個(gè)操作的平均時(shí)間(秒、毫秒、納秒等)。
  • thrpt:每秒完成的操作次數(shù)(ops/s)。

b.示例:8.584

Error

  • 說(shuō)明:結(jié)果的標(biāo)準(zhǔn)誤差(Standard Error),表示結(jié)果的不確定性。
  • 示例:0.175

Units

  • 說(shuō)明:結(jié)果的單位
  • 示例:ns/op(每操作納秒)

性能排序

  1. (+)plusOperator:6.154 ± 0.119 ns/op
  2. concat:8.584 ± 0.175 ns/op
  3. stringBuilder:11.560 ± 0.216 ns/op
  4. stringBuffer:12.340 ± 0.150 ns/op
  5. stringJoiner:29.932 ± 0.236 ns/op
  6. join:28.210 ± 0.241 ns/op
  7. stream:34.293 ± 0.284 ns/op
  8. format:409.691 ± 2.941 ns/op
責(zé)任編輯:武曉燕 來(lái)源: Spring全家桶實(shí)戰(zhàn)案例源碼
相關(guān)推薦

2013-06-24 15:16:29

Java字符串拼接

2025-02-13 08:13:29

C#字符串拼接

2024-12-20 12:10:19

2023-10-31 18:57:02

Java字符串

2025-03-14 08:35:00

字符串C#字符串拼接

2024-12-23 07:38:20

2023-12-11 08:39:14

Go語(yǔ)言字符串拼

2019-02-27 09:08:20

Java 8StringJoineIDEA

2011-07-11 16:00:22

字符串拼接

2022-11-25 07:53:26

bash腳本字符串

2023-06-12 08:17:38

Java字符串拼接

2021-06-11 18:08:00

Java字符串拼接

2022-03-18 09:42:54

JavaString

2019-12-17 15:49:44

Java語(yǔ)言字符串

2016-12-27 09:46:55

Java 8StringBuild

2021-05-31 07:57:00

拼接字符串Java

2017-01-19 11:26:55

Java 8StringBuild

2019-12-25 15:41:50

JavaScript程序員編程語(yǔ)言

2021-10-31 23:01:50

語(yǔ)言拼接字符串

2016-10-12 10:18:53

Java字符串源碼分析
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)