日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java中连接字符串的最佳方法

發布時間:2023/12/3 java 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java中连接字符串的最佳方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近有人問我這個問題–在Java中使用+運算符連接字符串是否對性能不利?

這讓我開始思考Java中連接字符串的不同方法,以及它們如何相互對抗。 這些是我要研究的方法:

  • 使用+運算符
  • 使用StringBuilder
  • 使用StringBuffer
  • 使用String.concat()
  • 使用String.join ( String.join新增功能)
  • 我也嘗試了String.format()但是那太慢了,以至于我暫時不在本文中介紹。

    在繼續之前,我們應該分離兩個用例:

  • 將兩個字符串作為單個調用連接在一起,例如在日志消息中。 因為這只是一個電話,您可能會認為性能幾乎不是問題,但結果仍然很有趣,并且可以闡明該主題。
  • 在一個循環中連接兩個字符串。 性能尤其是一個問題,尤其是在循環較大的情況下。
  • 我最初的想法和問題如下:

  • +運算符是用StringBuilder實現的,因此至少在連接兩個String的情況下,它應產生與StringBuilder類似的結果。 幕后到底發生了什么?
  • 在所有類都是出于連接字符串并取代StringBuffer的目的而設計的之后,StringBuilder應該是最有效的方法。 但是,與String.concat()相比,創建StringBuilder的開銷是多少?
  • StringBuffer是用于連接字符串的原始類–不幸的是,其方法是同步的。 確實不需要同步,并且隨后將其替換為未同步的StringBuilder。 問題是,JIT是否優化了同步?
  • String.concat()應該適用于2個字符串,但是在循環中是否可以正常工作?
  • String.join()具有比StringBuilder更多的功能,如果我們指示它使用空的定界符來聯接String,它將如何影響性能?
  • 我要解決的第一個問題是+運算符的工作方式。 我一直都知道它在幕后使用了StringBuilder,但是要證明這一點,我們需要檢查字節碼。

    如今 ,查看字節碼最簡單的方法是使用JITWatch ,這是一個非常出色的工具,旨在了解JIT如何編譯您的代碼。 它有一個很棒的視圖,您可以在其中與字節碼(如果要進入該級別,還可以是機器碼)并排查看源代碼。

    這是一個非常簡單的方法plus2()的字節碼,我們可以看到確實在第6行上創建了一個StringBuilder并附加了變量a(第14行)和b(第18行)。

    我認為將其與StringBuffer的手工使用進行比較會很有趣,因此我創建了另一個方法build2(),結果如下。

    此處生成的字節碼不如plus()方法那么緊湊。 StringBuilder存儲在變量高速緩存中(第13行),而不是僅留在堆棧上。 我不知道為什么會這樣,但是JIT可能能夠做到這一點,我們將不得不看看時機如何。

    無論如何,如果用plus運算符和StringBuilder將2個字符串連接起來的結果顯著不同,那將是非常令人驚訝的。

    我寫了一個小型的JMH測試來確定不同方法的執行方式。 讓我們首先看一下兩個Strings測試。 參見下面的代碼:

    package org.sample;import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole;import java.util.UUID; import java.util.concurrent.TimeUnit;@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) @Fork(1) @State(Scope.Thread) public class LoopStringsBenchmark {private String[] strings;@Setuppublic void setupTest(){strings = new String[100];for(int i = 0; i<100; i++) {strings[i] = UUID.randomUUID().toString().substring(0, 10);}}@Benchmarkpublic void testPlus(Blackhole bh) {String combined = "";for(String s : strings) {combined = combined + s;}bh.consume(combined);}@Benchmarkpublic void testStringBuilder(Blackhole bh) {StringBuilder sb = new StringBuilder();for(String s : strings) {sb.append(s);}bh.consume(sb.toString());}@Benchmarkpublic void testStringBuffer(Blackhole bh) {StringBuffer sb = new StringBuffer();for(String s : strings) {sb.append(s);}bh.consume(sb.toString());}@Benchmarkpublic void testStringJoiner(Blackhole bh) {bh.consume(String.join("", strings));}@Benchmarkpublic void testStringConcat(Blackhole bh) {String combined = "";for(String s : strings) {combined.concat(s);}bh.consume(combined);} }

    結果看起來像這樣:

    顯而易見的贏家是String.concat()。 毫不奇怪,因為它不必為每次調用創建StringBuilder / StringBuffer而付出性能損失。 雖然確實需要每次都創建一個新的String(這將在以后變得很重要),但是對于連接兩個Sting的非常簡單的情況,它更快。

    另一點是,盡管產生了額外的字節碼,但正如我們預期的那樣,plus和StringBuilder是等效的。 StringBuffer僅比StringBuilder慢一點,這很有趣,這表明JIT必須在做一些魔術來優化同步。

    下一個測試將創建一個由100個字符串組成的數組,每個字符串包含10個字符。 基準比較了將100個字符串連接在一起的不同方法所花費的時間。 參見下面的代碼:

    這次的結果看起來完全不同:

    在這里,加號方法確實遭受了損失。 每次循環時創建StringBuilder的開銷都非常大。 您可以在字節碼中清楚地看到這一點:

    您可以看到每次執行循環時都會創建一個新的StringBuilder(第30行)。 可以爭論的是,JIT應該發現這一點并能夠對其進行優化,但是事實并非如此,并且使用+變得非常慢。

    同樣,StringBuilder和StringBuffer的性能完全相同,但是這次它們都比String.concat()快。 String.concat()為在循環的每次迭代中創建新的String付出的代價最終會增加,并且StringBuilder變得更有效率。

    給定可以添加到此方法的所有其他功能,String.join()效果很好,但是,正如預期的那樣,對于純串聯而言,它不是最佳選擇。

    摘要

    如果要在單行代碼中連接字符串,我將使用+運算符,因為它最易讀,并且性能對于單次調用實際上并不重要。 還要提防String.concat(),因為您幾乎肯定會需要執行空檢查 ,而其他方法則不需要這樣做。

    在循環中串聯字符串時,應使用StringBuilder。 您可以使用StringBuffer,但我不一定在所有情況下都信任JIT來像基準測試中那樣高效地優化同步。

    我的所有結果都是使用JMH取得的,并且都帶有通常的健康警告 。

    翻譯自: https://www.javacodegeeks.com/2015/02/optimum-method-concatenate-strings-java.html

    總結

    以上是生活随笔為你收集整理的Java中连接字符串的最佳方法的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。