JavaScript の文字列は不変ですか? JavaScript に「文字列ビルダー」は必要ですか? 質問する

JavaScript の文字列は不変ですか? JavaScript に「文字列ビルダー」は必要ですか? 質問する

JavaScript は不変文字列と可変文字列のどちらを使用しますか? 「文字列ビルダー」は必要ですか?

ベストアンサー1

これらは不変です。 のような方法で文字列内の文字を変更することはできませんvar myString = "abbdef"; myString[2] = 'c'。 のような文字列操作メソッドは、trimslice新しい文字列を返します。

同様に、同じ文字列への参照が2つある場合、一方を変更してももう一方には影響しません。

let a = b = "hello";
a = a + " world";
// b is not affected

神話の解明 - 文字列の連結は遅くない

私はいつも、Ash が回答で言及していたこと (Array.join を使用すると連結が高速になる) を聞いていたので、文字列を連結するさまざまな方法と、最も高速な方法を StringBuilder に抽象化する方法をテストしたいと考えました。これが真実かどうかを確認するために、いくつかのテストを書きました (真実ではありません)。

これは、プッシュを回避し、配列を使用して文字列を保存し、最後にそれらを結合する、最も速い方法であると信じていました。

class StringBuilderArrayIndex {
  array = [];
  index = 0;
  append(str) {
    this.array[this.index++] = str 
  }
  toString() {
    return this.array.join('')
  }
}

いくつかのベンチマーク

  • 以下のスニペットのテストケースを読んでください
  • スニペットを実行する
  • ベンチマークボタンを押してテストを実行し、結果を確認します

私は2種類のテストを作成しました

  • 配列インデックスを使用して回避しArray.pushArray.join
  • 直線的な文字列の連結

これらのテストごとに、定数値とランダムな文字列を追加してループしました。

<script benchmark>

  // Number of times to loop through, appending random chars
  const APPEND_COUNT = 1000;
  const STR = 'Hot diggity dizzle';
  
  function generateRandomString() {
    const characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    const length = Math.floor(Math.random() * 10) + 1; // Random length between 1 and 10
    let result = '';

    for (let i = 0; i < length; i++) {
      const randomIndex = Math.floor(Math.random() * characters.length);
      result += characters.charAt(randomIndex);
    }
    return result;
  }

  const randomStrings = Array.from({length: APPEND_COUNT}, generateRandomString);
  
  class StringBuilderStringAppend {
    str = '';

    append(str) {
      this.str += str;
    }

    toString() {
      return this.str;
    }
  }
  
  class StringBuilderArrayIndex {
    array = [];
    index = 0;

    append(str) {
      this.array[this.index] = str;
      this.index++;
    }

    toString() {
      return this.array.join('');
    }
  }

  // @group Same string 'Hot diggity dizzle'

  // @benchmark array push & join 
  {
    const sb = new StringBuilderArrayIndex();

    for (let i = 0; i < APPEND_COUNT; i++) {
      sb.append(STR)
    }
    sb.toString();
  }

  // @benchmark string concatenation
  {
    const sb = new StringBuilderStringAppend();

    for (let i = 0; i < APPEND_COUNT; i++) {
      sb.append(STR)
    }
    sb.toString();
  }

  // @group Random strings

  // @benchmark array push & join
  {
    const sb = new StringBuilderArrayIndex();

    for (let i = 0; i < APPEND_COUNT; i++) {
      sb.append(randomStrings[i])
    }
    sb.toString();
  }

  // @benchmark string concatenation
  {
    const sb = new StringBuilderStringAppend();

    for (let i = 0; i < APPEND_COUNT; i++) {
      sb.append(randomStrings[i])
    }
    sb.toString();
  }
  
  
</script>
<script src="https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js"></script>

調査結果

現在、すべての最新ブラウザは文字列の連結をより適切に、少なくとも 2 倍の速度で処理します。

i-12600k (Alexander Nenashev 氏によって追加)

クローム/117

--------------------------------------------------------------------
Same string 'Hot diggity dizzle'
    string concatenation   1.0x  |  x100000  224  232  254  266  275
    array push & join      3.2x  |  x100000  722  753  757  762  763
Random strings
    string concatenation   1.0x  |  x100000  261  268  270  273  279
    array push & join      5.4x  |   x10000  142  147  148  155  166
--------------------------------------------------------------------
https://github.com/silentmantra/benchmark

ファイアフォックス/118

--------------------------------------------------------------------
Same string 'Hot diggity dizzle'
    string concatenation   1.0x  |  x100000  304  335  353  358  370
    array push & join      9.5x  |   x10000  289  300  301  306  309
Random strings
    string concatenation   1.0x  |  x100000  334  337  345  349  377
    array push & join      5.1x  |   x10000  169  176  176  176  180
--------------------------------------------------------------------
https://github.com/silentmantra/benchmark

2023年10月の2.4GHz 8コアi9 Macでの結果は以下の通りです。

クロム

--------------------------------------------------------------------
Same string 'Hot diggity dizzle'
    string concatenation   1.0x  |  x100000  574  592  594  607  613
    array push & join      2.7x  |   x10000  156  157  159  164  165
Random strings
    string concatenation   1.0x  |  x100000  657  663  669  675  680
    array push & join      4.3x  |   x10000  283  285  295  298  311
--------------------------------------------------------------------
https://github.com/silentmantra/benchmark

ファイアフォックス

--------------------------------------------------------------------
Same string 'Hot diggity dizzle'
    string concatenation   1.0x  |  x100000  546  648  659  663  677
    array push & join      5.8x  |   x10000  314  320  326  331  335
Random strings
    string concatenation   1.0x  |  x100000  647  739  764  765  804
    array push & join      2.9x  |   x10000  187  188  199  219  231
--------------------------------------------------------------------
https://github.com/silentmantra/benchmark

勇敢な

--------------------------------------------------------------------
Same string 'Hot diggity dizzle'
    string concatenation   1.0x  |  x100000  566  571  572  579  600
    array push & join      2.5x  |   x10000  144  145  159  162  166
Random strings
    string concatenation   1.0x  |  x100000  649  658  659  663  669
    array push & join      4.4x  |   x10000  285  285  290  292  300
--------------------------------------------------------------------
https://github.com/silentmantra/benchmark `

サファリ

--------------------------------------------------------------------
Same string 'Hot diggity dizzle'
    string concatenation   1.0x  |  x10000   76   77   77   79   82
    array push & join      2.2x  |  x10000  168  168  174  178  186
Random strings
    string concatenation   1.0x  |  x100000  878  884  889  892  903
    array push & join      2.3x  |   x10000  199  200  202  202  204
--------------------------------------------------------------------
https://github.com/silentmantra/benchmark `

オペラ

--------------------------------------------------------------------
Same string 'Hot diggity dizzle'
    string concatenation   1.0x  |  x100000  577  579  581  584  608
    array push & join      2.7x  |   x10000  157  162  165  166  171
Random strings
    string concatenation   1.0x  |  x100000  688  694  740  750  781
    array push & join      4.2x  |   x10000  291  315  316  317  379
--------------------------------------------------------------------
https://github.com/silentmantra/benchmark

おすすめ記事