🔩

[PowerShell]文字列を結合する13種類の方法(処理速度の計測もあり)

2024/02/06に公開

概要

ネット記事の情報から、PowerShellで文字列結合する場合はパフォーマンスを考慮すると、
“とりあえずStringBuilderクラスのAppendメソッドを使用すればよい。”という認識でした。

今回の結果からも処理速度の観点では、その結論で間違いなさそうです。

しかし、以前からStringBuilderクラスは可読性が低く、簡単にコーディングする事も多いPowerShellスクリプトと相性が良くないと感じていました。

今回、PowerShellスクリプトで小規模のツールを作成するときは「必ずしもStringBuilderクラスを使用しなくても良いのか」をテーマに、
PowerShellの文字列結合方法の洗い出し と それぞれの結合方法によるパフォーマンステスト を行った結果をまとめてみました。

この記事のターゲット

  • PowerShellユーザーの方
  • 目的・用途ごとに最適な文字列を結合する方法を探している方
  • 結合方法ごとのパフォーマンスを知りたい方

環境

PowerShellのバージョン

PowerShellのバージョン
PS C:\Users\"ユーザー名"> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.3.10
PSEdition                      Core
GitCommitId                    7.3.10
OS                             Microsoft Windows 10.0.19045
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

PS C:\Users\"ユーザー名">

OSのバージョン

Windows 10 Pro環境

Get-WmiObjectコマンド
PS C:\Users\"ユーザー名"> Get-CimInstance CIM_OperatingSystem

SystemDirectory     Organization BuildNumber RegisteredUser SerialNumber            Version
---------------     ------------ ----------- -------------- ------------            -------
C:\WINDOWS\system32              19045       XXXXX          00000-00000-00000-AAAAA 10.0.19045
                                             ^^^^^          ^^^^^ ^^^^^ ^^^^^ ^^^^^
                                             ↑マスク       ↑マスク

PS C:\Users\"ユーザー名">

マシンスペック

種類 内容
CPU Intel(R) Core(TM) i3-8100T CPU @ 3.10GHz
CPU世代 第8世代
コア数 4 コア
スレッド数 4 スレッド
メモリー 16GB
PowerShellのコマンドレットで性能測定 < クリックで折りたたみが開く >
コマンドで性能測定
# 計測
PS C:\Users\"ユーザー名"> winsat formal -restart clean
PS C:\Users\"ユーザー名">
# 計測結果の表示
PS C:\Users\"ユーザー名"> Get-CimInstance Win32_WinSAT

CPUScore              : 8.9
D3DScore              : 9.9
DiskScore             : 8.4
GraphicsScore         : 6.7
MemoryScore           : 8.9
TimeTaken             : MostRecentAssessment
WinSATAssessmentState : 1
WinSPRLevel           : 6.7
PSComputerName        :


PS C:\Users\"ユーザー名">

PowerShellにおける文字列結合方法の一覧

詳細は後述していますが、Bing AIで調べた結果自身で調べた結果 をまとめました。

かなり限定的な使用方法 や 使い方が一般的でない方法 も含まれていますが、大きくわけて13種類の方法がありました。

また、一部の結合方法に関してですが結合する変数のデータ型によってパフォーマンスにも影響があるのではと思い、
細かく結合方法をわけているものもあります。
それら細かい条件を含めると17種類になりました。

  • 演算子を使用した方法(大きくわけて4種類)

    1. 「 + 」演算子を使用した方法

      「 + 」演算子の使用例
      # 「 + 」演算子でAとBを結合
      $concatenated_str = $concat_parts_A + $concat_parts_B
      
      • データ型が通常の文字列(System.String)の場合
      • データ型が多段階配列(ジャグ配列)の文字列配列(System.String[])の場合
      • データ型が多次元配列の文字列配列(System.String[,])の場合
    2. 「 += 」演算子を使用した方法

      「 += 」演算子の使用例
      # 結合用の変数に部品Aを設定
      $concatenated_str = $concat_parts_A
      # 「 += 」演算子で結合用の変数に部品Bを追加
      $concatenated_str += $concat_parts_B
      
      • データ型が通常の文字列(System.String)の場合
      • データ型が多段階配列(ジャグ配列)の文字列配列(System.String[])の場合
      • データ型が多次元配列の文字列配列(System.String[,])の場合
    3. 「 -f 」演算子を使用した方法

      「 -f 」演算子の使用例
      # 「 -f 」演算子でAとBを結合
      $concatenated_str = "{0}{1}" -f $concat_parts_A, $concat_parts_B
      
    4. 「 -join 」演算子を使用した方法

      「 -join 」演算子の使用例
      # 「 -join 」演算子でAとBを結合
      $concatenated_str = $concat_parts_A, $concat_parts_B -join ''
      
  • メソッド・コマンドを使用した方法(大きくわけて9種類)

    1. ArrayListの「 Add 」メソッドを使用した方法

      ArrayListの「 Add 」メソッドの使用例
      [System.Collections.ArrayList]$concatenated_str = @()
      # ArrayListの「 Add 」メソッドでAを設定
      $concatenated_str.Add($concat_parts_A) | Out-Null
      # ArrayListの「 Add 」メソッドでBを追加
      $concatenated_str.Add($concat_parts_B) | Out-Null
      
    2. StringBuilderの「 Append 」メソッドを使用した方法

      StringBuilderの「 Append 」メソッドの使用例
      [System.Text.StringBuilder]$concatenated_str = New-Object System.Text.StringBuilder
      # StringBuilderの「 Append 」メソッドでAを設定
      $concatenated_str.Append($concat_parts_A) | Out-Null
      # StringBuilderの「 Append 」メソッドでBを追加
      $concatenated_str.Append($concat_parts_B) | Out-Null
      
    3. StringBuilderの「 AppendFormat 」メソッドを使用した方法

      StringBuilderの「 AppendFormat 」メソッドの使用例
      [System.Text.StringBuilder]$concatenated_str = New-Object System.Text.StringBuilder
      # StringBuilderの「 AppendFormat 」メソッドでAとBを結合
      $concatenated_str.AppendFormat("{0}{1}", $concat_parts_A, $concat_parts_B) | Out-Null
      
    4. System.Stringの「 Concat 」メソッドを使用した方法

      System.Stringの「 Concat 」メソッドの使用例
      # System.Stringの「 Concat 」メソッドでAとBを結合
      $concatenated_str = [System.String]::Concat($concat_parts_A, $concat_parts_B)
      
    5. System.Stringの「 Join 」メソッドを使用した方法

      System.Stringの「 Join 」メソッドの使用例
      # System.Stringの「 Join 」メソッドでAとBを結合
      $concatenated_str = [System.String]::Join('', $concat_parts_A, $concat_parts_B)
      
    6. Join-Stringコマンドレットを使用した方法(一般的ではない方法)

      Join-Stringコマンドレットの使用例
      # Join-StringコマンドレットでAとBを結合
      $concatenated_str = ($concat_parts_A, $concat_parts_B | Join-String -Separator '')
      
    7. Write-Outputコマンドレットを使用した方法(一般的ではない方法)

      Write-Outputコマンドレットの使用例
      # Write-OutputコマンドレットでAとBを結合
      $concatenated_str = (Write-Output "$($concat_parts_A)$($concat_parts_B)")
      
    8. ダブルコーテーション("")を使用した方法

      ダブルコーテーション("")の使用例
      # ダブルコーテーション("")でAとBを結合
      $concatenated_str = "$($concat_parts_A)$($concat_parts_B)"
      
    9. Join-Pathコマンドレットを使用した方法(限定的な状況での方法)
      このコマンドレットは、ファイルパスの作成を目的とした文字列結合で使用されるコマンドとなるため、強制的にファイルパスの区切り文字となります。
      Windows OSであれば、バックスラッシュ(\)が区切り文字。

      Join-Pathコマンドレットの使用例
      # Join-PathコマンドレットでAとBを結合
      $concatenated_str = Join-Path $concat_parts_A $concat_parts_B
      
13種類の結合方法を調べた方法 < クリックで折りたたみが開く >
  • 調査内容1:Bing AIで調べた結果

    • Bing AIに聞く(1回目)

      ❓ Bing AIへの依頼内容("より創造的に")

      PowerShellにおいて文字列を結合する方法をすべて洗い出してください。


      ✅ Bing AIからの回答結果

      PowerShellにおいて文字列を結合する方法は以下の通りです。

      • +演算子を使って文字列変数やリテラルを連結する方法 。例えば、$fullname = $lastname + $firstnameのように書きます。
      • -f演算子を使って文字列フォーマットを指定して変数の値を埋め込む方法。例えば、$message = "こんにちは! {0} {1}さん" -f $lastname, $firstnameのように書きます。
      • -join演算子を使って配列の要素を指定した区切り文字で連結する方法。例えば、$fullname = $names -join " "のように書きます。
      • Join-Pathコマンドレットを使ってパスの文字列を連結する方法。例えば、$path = Join-Path $dir $fileのように書きます。

      : [PowerShell 文字列を連結する | iPentec]
      : [PowerShellで文字列を結合する方法! 配列文字列結合も! - エク短|Extan.jp]
      : [PowerShellのJoin-Pathで文字列を結合しパスを取得する方法! - エク短|Extan.jp]

      Join-Pathコマンドレットの使用方法は、ファイルパスの結合に限定されているので、
      文字列の結合方法として入れるべきか微妙な所です。

    • Bing AIに聞く(2回目)

      ❓ Bing AIへの依頼内容("より創造的に")

      もっと文字列を結合する方法がありますので、
      すべて洗い出してください。


      ✅ Bing AIからの回答結果

      PowerShellにおいて文字列を結合する方法は、すでに紹介したもの以外にも以下のようなものがあります。

      • " (ダブルクォーテーション)で囲んだ文字列の中に変数を埋め込む方法¹。例えば、$fullname = "$lastname $firstname"のように書きます。
      • StringBuilderクラスを使って文字列を連結する方法²。例えば、$sb = [System.Text.StringBuilder]::new(); $sb.Append($lastname); $sb.Append($firstname); $fullname = $sb.ToString()のように書きます。
      • Write-Outputコマンドレットを使って文字列を出力する方法³。例えば、$fullname = Write-Output $lastname $firstnameのように書きます。

      ¹: PowerShellで文字列を結合する方法! 配列文字列結合も! - エク短|Extan.jp
      ²: [PowerShellでStringBuilderを使って文字列を連結する方法 - Qiita]
      ³: [PowerShellのWrite-Outputで文字列を出力する方法 - エク短|Extan.jp]

      ソース: Bing との会話 2023/12/21
      (1) PowerShell 文字列を連結する | iPentec. https://www.ipentec.com/document/powershell-string-join.
      (2) PowerShellで文字列を結合する方法!配列文字列結合も! - エク .... https://extan.jp/?p=10256.
      (3) PowerShell 文字列を連結する | iPentec. https://bing.com/search?q=PowerShellにおいる文字列を結合する方法.
      (4) PowerShellで文字列を結合する方法!配列文字列結合も! - エク .... https://extan.jp/?p=10256.
      (5) [PowerShell] [基本] 文字列どうしの結合方法 | PowerShell from .... https://blog.powershell-from.jp/?p=2819.
      (6) PowerShellのJoin-Pathで文字列を結合しパスを取得する方法 .... https://extan.jp/?p=10253.

    • Bing AIに聞く(3回目)

      ❓ Bing AIへの依頼内容("より創造的に")

      以上ですべての結合方法を洗い出せているように見えますが、
      まだ他の方法はあるでしょうか。

      → 2回目とまったく同じ結果があり。おそらくBing AIで調べられる結果は出きったよう。

  • 調査内容2:自身で調べた結果
    追加で深掘りして私自身で調べた結果、いくつかの方法が見つかりました。

Bing AIに洗い出した13種類の中のベストプラクティスを聞いた

さいしょにそれぞれの手法の要点をまとめるため、Bing AIにPowerShellにおける文字列結合のベストプラクティスを聞いた。

結果、ベストプラクティスは目的や状況によって異なるので判断できないとの結果で納得。
要約すると以下の回答結果だった。

  • 結合する文字列の数が少ない & 処理速度が重要視されない場合
    シンプルでわかりやすいコードとなるオススメの方法

    1. 「 + 」演算子
    2. 「 -f 」演算子
  • 結合する文字列の数が多い & 処理速度を重要視する場合
    効率的に文字列が結合可能となるオススメの方法

    1. StringBuilderクラスの「 Append 」メソッド
    2. StringBuilderクラスの「 AppendFormat 」メソッド
  • 文字列配列を結合する場合
    配列の結合にくわえて区切り文字の指定も可能となるオススメの方法

    1. 「 -join 」演算子
    2. System.Stringクラスの「 Join 」メソッド
  • 結合する文字列がパスの場合
    プラットフォームに応じて適切なパス区切りとなるオススメの方法

    1. 「 Join-Path 」コマンドレット

パフォーマンスを正とするならば、やはりStringBuilderクラスを使用する方法が良いとの事。

参考情報:Bing AIとのやりとりについて < クリックで折りたたみが開く >

❓ Bing AIへの依頼内容("より創造的に")

PowerShellにおける文字列を結合する下記方法の中でベストプラクティスを教えてください。

  • 演算子を使用した方法(4種類)

    1. 「 + 」演算子を使用した方法

      • データ型が通常の文字列(System.String)の場合
      • データ型が多段階配列(ジャグ配列)の文字列配列(System.String[])の場合
      • データ型が多次元配列の文字列配列(System.String[,])の場合
    2. 「 += 」演算子を使用した方法

      • データ型が通常の文字列(System.String)の場合
      • データ型が多段階配列(ジャグ配列)の文字列配列(System.String[])の場合
      • データ型が多次元配列の文字列配列(System.String[,])の場合
    3. 「 -f 」演算子を使用した方法

    4. 「 -join 」演算子を使用した方法

  • メソッド・コマンドを使用した方法(9種類)

    1. ArrayListの「 Add 」メソッドを使用した方法
    2. StringBuilderの「 Append 」メソッドを使用した方法
    3. StringBuilderの「 AppendFormat 」メソッドを使用した方法
    4. System.Stringの「 Concat 」メソッドを使用した方法
    5. System.Stringの「 Join 」メソッドを使用した方法
    6. Join-Stringコマンドレットを使用した方法
    7. Write-Outputコマンドレットを使用した方法
    8. ダブルコーテーション("")を使用した方法
    9. Join-Pathコマンドレットを使用した方法(限定的な状況で使用)

✅ Bing AIからの回答結果

こんにちは、これはBingです。😊

PowerShellにおける文字列を結合する方法はいくつかありますが、ベストプラクティスは状況によって異なります。一般的には、以下のような基準で選択すると良いでしょう。

  • 文字列の数が少なく、パフォーマンスが重要でない場合は、「 + 」演算子や「 -f 」演算子を使用するとシンプルで分かりやすいコードになります¹²。
  • 文字列の数が多く、パフォーマンスが重要な場合は、「 StringBuilder 」クラスの「 Append 」メソッドや「 AppendFormat 」メソッドを使用すると効率的に文字列を結合できます¹²。
  • 文字列の配列を結合する場合は、「 -join 」演算子や「 System.String 」クラスの「 Join 」メソッドを使用すると便利です¹²。区切り文字を指定することもできます。
  • パスの文字列を結合する場合は、「 Join-Path 」コマンドレットを使用すると、プラットフォームに応じて適切なパス区切り文字を自動的に挿入してくれます³。

以下に、各方法の例を示します。

# 「 + 」演算子を使用した方法
$name = "Bing"
$greeting = "Hello, " + $name + "!"
echo $greeting # Hello, Bing!

# 「 -f 」演算子を使用した方法
$name = "Bing"
$greeting = "Hello, {0}!" -f $name
echo $greeting # Hello, Bing!

# 「 StringBuilder 」クラスの「 Append 」メソッドを使用した方法
$sb = New-Object System.Text.StringBuilder
$sb.Append("Hello, ")
$sb.Append("Bing")
$sb.Append("!")
$greeting = $sb.ToString()
echo $greeting # Hello, Bing!

# 「 StringBuilder 」クラスの「 AppendFormat 」メソッドを使用した方法
$sb = New-Object System.Text.StringBuilder
$name = "Bing"
$sb.AppendFormat("Hello, {0}!", $name)
$greeting = $sb.ToString()
echo $greeting # Hello, Bing!

# 「 -join 」演算子を使用した方法
$words = "Hello", "Bing", "!"
$greeting = $words -join " "
echo $greeting # Hello Bing !

# 「 System.String 」クラスの「 Join 」メソッドを使用した方法
$words = "Hello", "Bing", "!"
$greeting = [System.String]::Join(" ", $words)
echo $greeting # Hello Bing !

# 「 Join-Path 」コマンドレットを使用した方法
$folder = "C:\Users"
$file = "Bing.txt"
$path = Join-Path $folder $file
echo $path # C:\Users\Bing.txt

以上が、PowerShellにおける文字列を結合する方法の一部です。他にも様々な方法がありますので、詳しくはこちらをご覧ください。👍

ソース: Bing との会話 2023/12/22
(1) Join について - PowerShell | Microsoft Learn. https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_join?view=powershell-7.3.
(2) How to correctly concatenate string in Powershell inline script .... https://stackoverflow.com/questions/59860674/how-to-correctly-concatenate-string-in-powershell-inline-script-in-azure-devops.
(3) How to Concatenate String in PowerShell? - SharePoint Diary. https://bing.com/search?q=PowerShell+string+concatenation+best+practices.
(4) How to concatenate strings using PowerShell? - TECHEPAGES. https://www.techepages.com/how-to-concatenate-strings-in-powershell/.

パフォーマンスの測定

まずパフォーマンスを測定する為、検証する為のコードを準備しました。

パフォーマンス測定の手法を選定

またまたBing AIに聞いた結果、いくつかの手法を提案してくれました。
提案された中で、より精密に測定が可能そうな System.Diagnostics.Stopwatchクラス を使った検証方法を選択しました。

Bing AIにPowerShellで処理速度を測定する手法を聞く < クリックで折りたたみが開く >
  • 処理速度を計測する方法
    • Bing AIに聞く(1回目)
      初回に確認した結果、下記2点の方法を洗い出しました。

      • Measure-Commandコマンドレットを使用した方法
      • Get-Dateコマンドレットを使用した方法
      Bing AIに聞く(1回目)のやり取り < クリックで折りたたみが開く >

      ❓ Bing AIへの依頼内容("より創造的に")

      PowerShellの処理を計測する方法を教えてください。
      また、ラインナップした方法それぞれの違いと使用用途、検証する際のサンプルコードについても教えてください。


      ✅ Bing AIからの回答結果

      こんにちは、これはBingです。PowerShellの処理を計測する方法についてお答えします。😊

      PowerShellの処理を計測するには、主に以下の2つの方法があります。

      • Measure-Commandコマンドレットを使用する方法
      • 開始時間と終了時間の差を計算する方法

      Measure-Commandコマンドレットは、処理の実行に要した時間をTimeSpan型で返す専用のコマンドレットです。¹ この方法は、処理時間を計測したい部分をカッコ内に記述するだけで簡単に使用できます。² また、TimeSpan型の変数は、書式指定文字列を使って指定した形式の文字列に変換できます。³

      開始時間と終了時間の差を計算する方法は、Get-Dateコマンドレットを使って処理の開始時間と終了時間を取得し、その差を計算する方法です。⁴ この方法は、Measure-Commandコマンドレットが使用できない場合や、複数の処理の時間を比較したい場合に便利です。

      以下に、それぞれの方法のサンプルコードを示します。

      • Measure-Commandコマンドレットを使用する方法
      # 3秒間、処理を一時停止する
      $TimeSpan = Measure-Command { Start-Sleep -Seconds 3 }
      
      # 処理にかかった時間を秒単位で出力する
      Write-Host ($TimeSpan.TotalSeconds)
      
      # 処理にかかった時間を日・時間・分・秒・ミリ秒の形式で出力する
      Write-Host $TimeSpan.ToString(\"d'日'h'時間'm'分's'秒'fff\")
      
      • 開始時間と終了時間の差を計算する方法
      # 処理の開始時間を取得する
      $StartTime = Get-Date
      
      # 3秒間、処理を一時停止する
      Start-Sleep -Seconds 3
      
      # 処理の終了時間を取得する
      $StopTime = Get-Date
      
      # 処理にかかった時間を秒単位で出力する
      Write-Host ($StopTime - $StartTime).TotalSeconds
      

      以上が、PowerShellの処理を計測する方法についての説明です。ご参考になれば幸いです。😊

      ¹: Measure-Command (Microsoft.PowerShell.Utility) - PowerShell
      ²: PowerShellで処理時間や処理の区間時間(ラップタイム)を計測 ...
      ³: カスタム TimeSpan 書式指定文字列 - PowerShell | Microsoft Docs
      ⁴: Windows(PowerShell)でコマンド・スクリプトの処理時間を計測する

      ソース: Bing との会話 2023/12/22
      (1) PowerShellで処理時間や処理の区間時間(ラップタイム)を計測 .... https://www.haruru29.net/blog/how-to-measure-processing-time-using-powershell/.
      (2) Windows(PowerShell)でコマンド・スクリプトの処理時間を計測する. https://pig-log.com/windows-measure-time/.
      (3) Windows(PowerShell)でコマンド・スクリプトの処理時間を計測する. https://bing.com/search?q=PowerShellの処理を計測する方法.
      (4) Measure-Command (Microsoft.PowerShell.Utility) - PowerShell. https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.utility/measure-command?view=powershell-7.3.
      (5) Measure-Command (Microsoft.PowerShell.Utility) - PowerShell. https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.utility/measure-command?view=powershell-7.3.
      (6) PowerShellで処理時間や処理の区間時間(ラップタイム)を計測 .... https://www.haruru29.net/blog/how-to-measure-processing-time-using-powershell/.
      (7) Windows(PowerShell)でコマンド・スクリプトの処理時間を計測する. https://pig-log.com/windows-measure-time/.

    • Bing AIに聞く(2回目)
      追加で確認した結果、あらたに下記2点の方法が見つかりました。

      • System.Diagnostics.Stopwatchクラスを使用した方法
      • Measure-Scriptコマンドレットを使用した方法
      Bing AIに聞く(2回目)のやり取り < クリックで折りたたみが開く >

      ❓ Bing AIへの依頼内容("より創造的に")

      他の方法もあると思いますので、洗い出して同じように違いと使用用途、検証する際のサンプルコードを教えてください。


      ✅ Bing AIからの回答結果

      はい、PowerShellの処理を計測する方法は他にもあります。😊

      • System.Diagnostics.Stopwatchクラスを使用する方法
      • Measure-Scriptコマンドレットを使用する方法

      System.Diagnostics.Stopwatchクラスは、高精度のタイマーを提供する.NET Frameworkのクラスです。 この方法は、Measure-Commandコマンドレットよりも細かい時間単位で計測できるという利点があります。 また、複数の処理の時間を比較したり、ラップタイムを取得したりすることもできます。

      Measure-Scriptコマンドレットは、PowerShellスクリプトの実行に要した時間を測定するためのコマンドレットです。 この方法は、Measure-Commandコマンドレットと同様に簡単に使用できますが、スクリプトの各行の実行時間やメモリ使用量などの詳細な情報を取得できるという利点があります。

      以下に、それぞれの方法のサンプルコードを示します。

      • System.Diagnostics.Stopwatchクラスを使用する方法
      # Stopwatchオブジェクトを作成する
      $Stopwatch = New-Object System.Diagnostics.Stopwatch
      
      # タイマーを開始する
      $Stopwatch.Start()
      
      # 3秒間、処理を一時停止する
      Start-Sleep -Seconds 3
      
      # タイマーを停止する
      $Stopwatch.Stop()
      
      # 処理にかかった時間を秒単位で出力する
      Write-Host ($Stopwatch.Elapsed.TotalSeconds)
      
      # 処理にかかった時間を日・時間・分・秒・ミリ秒・マイクロ秒・ナノ秒の形式で出力する
      Write-Host $Stopwatch.Elapsed.ToString(\"d'日'h'時間'm'分's'秒'fff'ミリ秒'ffff'マイクロ秒'fffffff'ナノ秒'\")
      
      • Measure-Scriptコマンドレットを使用する方法
      # スクリプトファイルのパスを指定する
      $ScriptPath = "C:\Work\datetime.ps1"
      
      # スクリプトの実行時間を測定する
      $Result = Measure-Script -Path $ScriptPath
      
      # スクリプト全体の実行時間を秒単位で出力する
      Write-Host ($Result.TotalTime.TotalSeconds)
      
      # スクリプトの各行の実行時間とメモリ使用量を出力する
      $Result | Select-Object Line, Time, Memory | Format-Table
      

      以上が、PowerShellの処理を計測する方法についての説明です。他にも方法があるかもしれませんが、私はこれらの方法しか知りません。ご了承ください。😊

      : Stopwatch クラス (System.Diagnostics) | Microsoft Docs
      : PowerShellで処理時間を計測する方法 - Qiita
      : PowerShellで処理時間や処理の区間時間(ラップタイム)を計測 ...
      : Measure-Script (PowerShellCookbook) - PowerShell
      : PowerShellでスクリプトの実行時間を測定する - ひとりぶろぐ

      ソース: Bing との会話 2023/12/22
      (1) PowerShellで処理時間や処理の区間時間(ラップタイム)を計測 .... https://www.haruru29.net/blog/how-to-measure-processing-time-using-powershell/.
      (2) Windows(PowerShell)でコマンド・スクリプトの処理時間を計測する. https://pig-log.com/windows-measure-time/.
      (3) Windows(PowerShell)でコマンド・スクリプトの処理時間を計測する. https://bing.com/search?q=PowerShellの処理を計測する方法.
      (4) Measure-Command (Microsoft.PowerShell.Utility) - PowerShell. https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.utility/measure-command?view=powershell-7.3.

以上、Bing AIに提案されたなかでSystem.Diagnostics.Stopwatchクラスを使用する方法を選択。
つづいてSystem.Diagnostics.Stopwatchクラスを使い検証するためのコード作成を依頼しました。

  • System.Diagnostics.Stopwatchクラスを使って処理の経過時間と平均時間を検証するコード
    Bing AIに検証するためコードの作成を依頼 < クリックで折りたたみが開く >

    ❓ Bing AIへの依頼内容("より創造的に")

    PowerShellにおいてSystem.Diagnostics.Stopwatchクラスを使用して処理経過時間と処理平均時間を計測、また検証するためのサンプルコードを作成してください。


    ✅ Bing AIからの回答結果

    はい、PowerShellにおいてSystem.Diagnostics.Stopwatchクラスを使用して処理経過時間と処理平均時間を計測、また検証するためのサンプルコードを作成してみます。😊

    以下のコードは、3つの異なる処理を実行し、それぞれの処理経過時間と処理平均時間を出力するものです。

    # Stopwatchオブジェクトを作成する
    $Stopwatch = New-Object System.Diagnostics.Stopwatch
    
    # 処理経過時間と処理平均時間を格納するハッシュテーブルを作成する
    $HashTable = @{}
    
    # 1つ目の処理: 1から100までの自然数の和を求める
    $Stopwatch.Start()
    $Sum = 0
    for ($i = 1; $i -le 100; $i++) {
        $Sum += $i
    }
    $Stopwatch.Stop()
    $HashTable["Sum"] = @{
        "Elapsed" = $Stopwatch.Elapsed.TotalMilliseconds
        "Average" = $Stopwatch.Elapsed.TotalMilliseconds / 100
    }
    
    # 2つ目の処理: 1から100までの自然数の積を求める
    $Stopwatch.Restart()
    $Product = 1
    for ($i = 1; $i -le 100; $i++) {
        $Product *= $i
    }
    $Stopwatch.Stop()
    $HashTable["Product"] = @{
        "Elapsed" = $Stopwatch.Elapsed.TotalMilliseconds
        "Average" = $Stopwatch.Elapsed.TotalMilliseconds / 100
    }
    
    # 3つ目の処理: 1から100までの自然数の平方根の和を求める
    $Stopwatch.Restart()
    $RootSum = 0
    for ($i = 1; $i -le 100; $i++) {
        $RootSum += [Math]::Sqrt($i)
    }
    $Stopwatch.Stop()
    $HashTable["RootSum"] = @{
        "Elapsed" = $Stopwatch.Elapsed.TotalMilliseconds
        "Average" = $Stopwatch.Elapsed.TotalMilliseconds / 100
    }
    
    # ハッシュテーブルの内容を出力する
    $HashTable | Format-Table -AutoSize
    

    このコードを実行すると、以下のような出力が得られます。

    Name    Elapsed Average
    ----    ------- -------
    Sum     0.0174  0.000174
    Product 0.0178  0.000178
    RootSum 0.0215  0.000215
    

    この出力から、3つの処理の中で最も時間がかかったのは、平方根の和を求める処理であることがわかります。また、各処理の平均時間は、処理経過時間を100で割った値になっています。

    以上が、PowerShellにおいてSystem.Diagnostics.Stopwatchクラスを使用して処理経過時間と処理平均時間を計測、また検証するためのサンプルコードについての説明です。ご参考になれば幸いです。😊

処理速度の検証

検証方法

前述で紹介したBing AIのコードを元にFunctionを作成しました。

Bing AIが作成した内容から大きな変化はありませんが、ポイントを上げると Functionとして定義した点Functionの引数でループ回数を指定するよう変更した点 が変化点です。

処理速度の検証に使用したPowerShellコード < クリックで折りたたみが開く >
パフォーマンステストしたコード
function VerificationProcessingSpeed {
    Param (
        [System.Int32]$loop = 10000
    )
    # Stopwatch作成
    $stopwatch = New-Object System.Diagnostics.Stopwatch
    # 結果表示用のハッシュテーブルを作成
    $result_hash = @{}
    # ヘッダー・フッター用
    $title_main = ''
    $title_sub1 = ''
    $title_sub2 = ''
    # 結合用の変数
    $concatenated_str = ''
    $to_join_str = "join_str"

    # ヘッダー
    Write-Host '*=================================================================*'
    Write-Host ''
    Write-Host "* ループ回数:$($loop.ToString()) の検証 Start"
    Write-Host ''
    Write-Host '*=================================================================*'
    Write-Host ''
    Write-Host ''

    # 演算子を使用した方法
    $title_main = '演算子を使用した方法'
    Write-Host " $($title_main): " 
    #   「 + 」演算子を使用した方法
    $title_sub1 = '「 + 」演算子を使用した方法'
    #       データ型が通常の文字列(System.String)の場合
    $title_sub2 = ' - ' + 'データ型が通常の文字列(System.String)の場合'
    Write-Host "    $($title_sub1)$($title_sub2): "

    # 計測
    [System.String]$concatenated_str = ''
    $stopwatch.Start()
    for ($i = 0; $i -lt $loop; $i++) {
        $concatenated_str = $concatenated_str + "$($to_join_str)$($i.ToString())"
    }
    $stopwatch.Stop()
    $result_hash['+ Operator & System.String'] = @{
        'Total時間' = $stopwatch.Elapsed.TotalMilliseconds
        '平均時間' = $stopwatch.Elapsed.TotalMilliseconds / $loop
    }
    $result_hash['+ Operator & System.String'] | Format-Table -AutoSize -Wrap

    #       データ型が多段階配列(ジャグ配列)の文字列配列(System.String[])の場合
    $title_sub2 = ' - ' + 'データ型が多段階配列(ジャグ配列)の文字列配列(System.String[])の場合'
    Write-Host "    $($title_sub1)$($title_sub2): "

    # 計測
    [System.String[]]$concatenated_str = @()
    $stopwatch.Restart()
    for ($i = 0; $i -lt $loop; $i++) {
        $concatenated_str = $concatenated_str + "$($to_join_str)$($i.ToString())"
    }
    $stopwatch.Stop()
    $result_hash['+ Operator & System.String[]'] = @{
        'Total時間' = $stopwatch.Elapsed.TotalMilliseconds
        '平均時間' = $stopwatch.Elapsed.TotalMilliseconds / $loop
    }
    $result_hash['+ Operator & System.String[]'] | Format-Table -AutoSize -Wrap

    #       データ型が多次元配列の文字列配列(System.String[,])の場合
    $title_sub2 = ' - ' + 'データ型が多次元配列の文字列配列(System.String[,])の場合'
    Write-Host "    $($title_sub1)$($title_sub2): "

    # 計測
    [System.String[,]]$concatenated_str = New-Object "System.String[,]" 1,1
    $stopwatch.Restart()
    for ($i = 0; $i -lt $loop; $i++) {
        $concatenated_str = $concatenated_str + "$($to_join_str)$($i.ToString())"
    }
    $stopwatch.Stop()
    $result_hash['+ Operator & System.String[,]'] = @{
        'Total時間' = $stopwatch.Elapsed.TotalMilliseconds
        '平均時間' = $stopwatch.Elapsed.TotalMilliseconds / $loop
    }
    $result_hash['+ Operator & System.String[,]'] | Format-Table -AutoSize -Wrap

    #   「 += 」演算子を使用した方法
    $title_sub1 = '「 += 」演算子を使用した方法'
    #       データ型が通常の文字列(System.String)の場合
    $title_sub2 = ' - ' + 'データ型が通常の文字列(System.String)の場合'
    Write-Host "    $($title_sub1)$($title_sub2): "

    # 計測
    [System.String]$concatenated_str = ''
    $stopwatch.Restart()
    for ($i = 0; $i -lt $loop; $i++) {
        $concatenated_str += ("$($to_join_str)$($i.ToString())")
    }
    $stopwatch.Stop()
    $result_hash['+= Operator & System.String'] = @{
        'Total時間' = $stopwatch.Elapsed.TotalMilliseconds
        '平均時間' = $stopwatch.Elapsed.TotalMilliseconds / $loop
    }
    $result_hash['+= Operator & System.String'] | Format-Table -AutoSize -Wrap

    #       データ型が多段階配列(ジャグ配列)の文字列配列(System.String[])の場合
    $title_sub2 = ' - ' + 'データ型が多段階配列(ジャグ配列)の文字列配列(System.String[])の場合'
    Write-Host "    $($title_sub1)$($title_sub2): "

    # 計測
    [System.String[]]$concatenated_str = @()
    $stopwatch.Restart()
    for ($i = 0; $i -lt $loop; $i++) {
        $concatenated_str += ("$($to_join_str)$($i.ToString())")
    }
    $stopwatch.Stop()
    $result_hash['+= Operator & System.String[]'] = @{
        'Total時間' = $stopwatch.Elapsed.TotalMilliseconds
        '平均時間' = $stopwatch.Elapsed.TotalMilliseconds / $loop
    }
    $result_hash['+= Operator & System.String[]'] | Format-Table -AutoSize -Wrap

    #       データ型が多次元配列の文字列配列(System.String[,])の場合
    $title_sub2 = ' - ' + 'データ型が多次元配列の文字列配列(System.String[,])の場合'
    Write-Host "    $($title_sub1)$($title_sub2): "

    # 計測
    [System.String[,]]$concatenated_str = New-Object "System.String[,]" 1,1
    $stopwatch.Restart()
    for ($i = 0; $i -lt $loop; $i++) {
        $concatenated_str += ("$($to_join_str)$($i.ToString())")
    }
    $stopwatch.Stop()
    $result_hash['+= Operator & System.String[,]'] = @{
        'Total時間' = $stopwatch.Elapsed.TotalMilliseconds
        '平均時間' = $stopwatch.Elapsed.TotalMilliseconds / $loop
    }
    $result_hash['+= Operator & System.String[,]'] | Format-Table -AutoSize -Wrap

    #   「 -f 」演算子を使用した方法
    $title_sub1 = '「 -f 」演算子を使用した方法'
    $title_sub2 = ''
    Write-Host "    $($title_sub1)$($title_sub2): "

    # 計測
    [System.String]$concatenated_str = ''
    $stopwatch.Restart()
    for ($i = 0; $i -lt $loop; $i++) {
        $concatenated_str = "{0}{1}" -f $concatenated_str, "$($to_join_str)$($i.ToString())"
    }
    $stopwatch.Stop()
    $result_hash['-f Operator'] = @{
        'Total時間' = $stopwatch.Elapsed.TotalMilliseconds
        '平均時間' = $stopwatch.Elapsed.TotalMilliseconds / $loop
    }
    $result_hash['-f Operator'] | Format-Table -AutoSize -Wrap

    #   「 -join 」演算子を使用した方法
    $title_sub1 = '「 -join 」演算子を使用した方法'
    $title_sub2 = ''
    Write-Host "    $($title_sub1)$($title_sub2): "

    # 計測
    [System.String]$concatenated_str = ''
    $stopwatch.Restart()
    for ($i = 0; $i -lt $loop; $i++) {
        $concatenated_str = $concatenated_str, "$($to_join_str)$($i.ToString())" -join ''
    }
    $stopwatch.Stop()
    $result_hash['-join Operator'] = @{
        'Total時間' = $stopwatch.Elapsed.TotalMilliseconds
        '平均時間' = $stopwatch.Elapsed.TotalMilliseconds / $loop
    }
    $result_hash['-join Operator'] | Format-Table -AutoSize -Wrap

    # メソッド・コマンドを使用した方法
    $title_main = 'メソッド・コマンドを使用した方法'
    Write-Host " $($title_main): " 
    #   ArrayListの「 Add 」メソッドを使用した方法
    $title_sub1 = 'ArrayListの「 Add 」メソッドを使用した方法'
    $title_sub2 = ''
    Write-Host "    $($title_sub1)$($title_sub2): "

    # 計測
    [System.Collections.ArrayList]$concatenated_str = @()
    $stopwatch.Restart()
    for ($i = 0; $i -lt $loop; $i++) {
        $concatenated_str.Add("$($to_join_str)$($i.ToString())") | Out-Null
    }
    $stopwatch.Stop()
    $result_hash['ArrayList - Add'] = @{
        'Total時間' = $stopwatch.Elapsed.TotalMilliseconds
        '平均時間' = $stopwatch.Elapsed.TotalMilliseconds / $loop
    }
    $result_hash['ArrayList - Add'] | Format-Table -AutoSize -Wrap

    #   StringBuilderの「 Append 」メソッドを使用した方法
    $title_sub1 = 'StringBuilderの「 Append 」メソッドを使用した方法'
    $title_sub2 = ''
    Write-Host "    $($title_sub1)$($title_sub2): "

    # 計測
    [System.Text.StringBuilder]$concatenated_str = New-Object System.Text.StringBuilder
    $stopwatch.Restart()
    for ($i = 0; $i -lt $loop; $i++) {
        $concatenated_str.Append("$($to_join_str)$($i.ToString())") | Out-Null
    }
    $stopwatch.Stop()
    $result_hash['StringBuilder - Append'] = @{
        'Total時間' = $stopwatch.Elapsed.TotalMilliseconds
        '平均時間' = $stopwatch.Elapsed.TotalMilliseconds / $loop
    }
    $result_hash['StringBuilder - Append'] | Format-Table -AutoSize -Wrap

    #   StringBuilderの「 AppendFormat 」メソッドを使用した方法
    $title_sub1 = 'StringBuilderの「 AppendFormat 」メソッドを使用した方法'
    $title_sub2 = ''
    Write-Host "    $($title_sub1)$($title_sub2): "

    # 計測
    [System.Text.StringBuilder]$concatenated_str = New-Object System.Text.StringBuilder
    $stopwatch.Restart()
    for ($i = 0; $i -lt $loop; $i++) {
        $concatenated_str.AppendFormat("{0}", "$($to_join_str)$($i.ToString())") | Out-Null
    }
    $stopwatch.Stop()
    $result_hash['StringBuilder - AppendFormat'] = @{
        'Total時間' = $stopwatch.Elapsed.TotalMilliseconds
        '平均時間' = $stopwatch.Elapsed.TotalMilliseconds / $loop
    }
    $result_hash['StringBuilder - AppendFormat'] | Format-Table -AutoSize -Wrap

    #   System.Stringの「 Concat 」メソッドを使用した方法
    $title_sub1 = 'System.Stringの「 Concat 」メソッドを使用した方法'
    $title_sub2 = ''
    Write-Host "    $($title_sub1)$($title_sub2): "

    # 計測
    [System.String]$concatenated_str = ''
    $stopwatch.Restart()
    for ($i = 0; $i -lt $loop; $i++) {
        $concatenated_str = [System.String]::Concat($concatenated_str, "$($to_join_str)$($i.ToString())")
    }
    $stopwatch.Stop()
    $result_hash['System.String - Concat'] = @{
        'Total時間' = $stopwatch.Elapsed.TotalMilliseconds
        '平均時間' = $stopwatch.Elapsed.TotalMilliseconds / $loop
    }
    $result_hash['System.String - Concat'] | Format-Table -AutoSize -Wrap

    #   System.Stringの「 Join 」メソッドを使用した方法
    $title_sub1 = 'System.Stringの「 Join 」メソッドを使用した方法'
    $title_sub2 = ''
    Write-Host "    $($title_sub1)$($title_sub2): "

    # 計測
    [System.String]$concatenated_str = ''
    $stopwatch.Restart()
    for ($i = 0; $i -lt $loop; $i++) {
        $concatenated_str = [System.String]::Join('', $concatenated_str, "$($to_join_str)$($i.ToString())")
    }
    $stopwatch.Stop()
    $result_hash['System.String - Join'] = @{
        'Total時間' = $stopwatch.Elapsed.TotalMilliseconds
        '平均時間' = $stopwatch.Elapsed.TotalMilliseconds / $loop
    }
    $result_hash['System.String - Join'] | Format-Table -AutoSize -Wrap

    #   Join-Stringコマンドレットを使用した方法
    $title_sub1 = 'Join-Stringコマンドレットを使用した方法'
    $title_sub2 = ''
    Write-Host "    $($title_sub1)$($title_sub2): "

    # 計測
    [System.String]$concatenated_str = ''
    $stopwatch.Restart()
    for ($i = 0; $i -lt $loop; $i++) {
        $concatenated_str = $concatenated_str, "$($to_join_str)$($i.ToString())" | Join-String -Separator ''
    }
    $stopwatch.Stop()
    $result_hash['Join-String CommandLet'] = @{
        'Total時間' = $stopwatch.Elapsed.TotalMilliseconds
        '平均時間' = $stopwatch.Elapsed.TotalMilliseconds / $loop
    }
    $result_hash['Join-String CommandLet'] | Format-Table -AutoSize -Wrap

    #   Write-Outputコマンドレットを使用した方法
    $title_sub1 = 'Write-Outputコマンドレットを使用した方法'
    $title_sub2 = ''
    Write-Host "    $($title_sub1)$($title_sub2): "

    # 計測
    [System.String]$concatenated_str = ''
    $stopwatch.Restart()
    for ($i = 0; $i -lt $loop; $i++) {
        $concatenated_str = (Write-Output "$($concatenated_str)$($to_join_str)$($i.ToString())")
    }
    $stopwatch.Stop()
    $result_hash['Write-Output CommandLet'] = @{
        'Total時間' = $stopwatch.Elapsed.TotalMilliseconds
        '平均時間' = $stopwatch.Elapsed.TotalMilliseconds / $loop
    }
    $result_hash['Write-Output CommandLet'] | Format-Table -AutoSize -Wrap

    #   ダブルコーテーション(`""`)を使用した方法
    $title_sub1 = 'ダブルコーテーション(`""`)を使用した方法'
    $title_sub2 = ''
    Write-Host "    $($title_sub1)$($title_sub2): "

    # 計測
    [System.String]$concatenated_str = ''
    $stopwatch.Restart()
    for ($i = 0; $i -lt $loop; $i++) {
        $concatenated_str = "$($concatenated_str)$($to_join_str)$($i.ToString())"
    }
    $stopwatch.Stop()
    $result_hash['Double Quotation囲み'] = @{
        'Total時間' = $stopwatch.Elapsed.TotalMilliseconds
        '平均時間' = $stopwatch.Elapsed.TotalMilliseconds / $loop
    }
    $result_hash['Double Quotation囲み'] | Format-Table -AutoSize -Wrap

    #   Join-Pathコマンドレットを使用した方法(限定的な状況で使用)
    $title_sub1 = 'Join-Pathコマンドレットを使用した方法(限定的な状況で使用)'
    $title_sub2 = ''
    Write-Host "    $($title_sub1)$($title_sub2): "

    # 計測
    # 変数の中身が空文字だとエラーが発生する為、初期の文字列を代入
    [System.String]$concatenated_str = 'first_str'
    $stopwatch.Restart()
    for ($i = 0; $i -lt $loop; $i++) {
        $concatenated_str = Join-Path $concatenated_str "$($to_join_str)$($i.ToString())"
    }
    $stopwatch.Stop()
    $result_hash['Join-Path CommandLet'] = @{
        'Total時間' = $stopwatch.Elapsed.TotalMilliseconds
        '平均時間' = $stopwatch.Elapsed.TotalMilliseconds / $loop
    }
    $result_hash['Join-Path CommandLet'] | Format-Table -AutoSize -Wrap

    # 結果表示
    Write-Host '*-----------------------------------------------------------------*'
    $result_hash | Format-Table -AutoSize -Wrap
    Write-Host ''

    # フッター
    Write-Host '*=================================================================*'
    Write-Host ''
    Write-Host "* ループ回数:$($loop.ToString()) の検証 End"
    Write-Host ''
    Write-Host '*=================================================================*'
    Write-Host ''
    Write-Host ''
}
参考情報:StopwatchクラスのStart/Reset/Restartの違い < クリックで折りたたみが開く >

❓ Bing AIへの依頼内容("より創造的に")

PowerShellにおけるSystem.Diagnostics.Stopwatchのメソッドである下記3点の違いと使用用途は
・Startメソッド
・Resetメソッド
・Restartメソッド


✅ Bing AIからの回答結果

PowerShellにおけるSystem.Diagnostics.Stopwatchのメソッドについてお尋ねですね。😊

System.Diagnostics.Stopwatchは、経過時間を正確に計測するために使用できるクラスです¹。Startメソッド、Resetメソッド、Restartメソッドの違いと使用用途は以下の通りです。

  • Startメソッドは、経過時間の計測を開始します²。Stopwatchがすでに実行されている場合は、何も起こりません²。Stopwatchが複数の間隔を測定する場合は、Startメソッドは現在の経過時間値からの時間の測定を再開します²。
  • Resetメソッドは、経過時間の計測を停止し、累積経過時間をクリアします³。Stopwatchが実行されていない場合も、累積経過時間がリセットされます³。Resetメソッドは、新しい時間間隔の測定を開始する前に、Stopwatchの状態を初期化するために使用します³。
  • Restartメソッドは、経過時間の計測を停止し、累積経過時間をクリアし、再び経過時間の計測を開始します⁴。Restartメソッドは、ResetメソッドとStartメソッドを一つのコマンドで使用することと同じです⁴。

Stopwatchクラスの詳細な使い方や例については、こちらのリファレンスをご覧ください。他にも、PowerShellで経過時間を計測する方法はこちらや[こちら]に紹介されています。

PowerShellに関するご質問がありましたら、お気軽にお聞かせください。😊

ソース: Bing との会話 2023/12/22
(1) Stopwatch クラス (System.Diagnostics) | Microsoft Learn. https://learn.microsoft.com/ja-jp/dotnet/api/system.diagnostics.stopwatch?view=net-8.0.
(2) Stopwatch.Stop メソッド (System.Diagnostics) | Microsoft Learn. https://learn.microsoft.com/ja-jp/dotnet/api/system.diagnostics.stopwatch.stop?view=net-8.0.
(3) Stopwatch.Start メソッド (System.Diagnostics) | Microsoft Learn. https://bing.com/search?q=PowerShellにおけるSystem.Diagnostics.Stopwatchのメソッドである下記3点の違いと使用用途は\n・Startメソッド\n・Resetメソッド\n・Restartメソッド.
(4) Stopwatch.Start メソッド (System.Diagnostics) | Microsoft Learn. https://learn.microsoft.com/ja-jp/dotnet/api/system.diagnostics.stopwatch.start?view=net-7.0.
(5) Stopwatch クラス (System.Diagnostics) | Microsoft Learn. https://learn.microsoft.com/ja-jp/dotnet/api/system.diagnostics.stopwatch?view=net-8.0.
(6) undefined. https://bing.com/search?q=.

検証結果

以下が文字列を結合する方法ごとに 平均時間(1処理の平均時間)Total時間(全処理の経過時間) を測定しました。

2024.07 ここから追記
表のみ掲載していましたが、グラフの方が比較しやすいと思うので追記しました。

処理速度の測定結果(1回目のグラフ)

PowerShellで複数の文字列結合方法で処理速度を測定した結果。1回目に計測したグラフ
画像:PowerShell文字列結合の処理速度を測定した結果(1回目)

処理速度の測定結果(2回目のグラフ)

PowerShellで複数の文字列結合方法で処理速度を測定した結果。2回目に計測したグラフ
画像:PowerShell文字列結合の処理速度を測定した結果(2回目)

処理速度の測定結果(3回目のグラフ)

PowerShellで複数の文字列結合方法で処理速度を測定した結果。3回目に計測したグラフ
画像:PowerShell文字列結合の処理速度を測定した結果(3回目)

追記はここまで

測定結果のTotal時間を軸に作成した表は以下のとおりです。
Total時間の昇順で並び替えを行っているので上位が一番処理速度が速く下にいくにつれて遅くなるという表記。

検証結果(合計、3回の測定を実施) < クリックで折りたたみが開く >
  • 1回目の結果(計測時間の単位:ミリ秒)

    順位 百回
    ----------
    方法
    百回
    ----------
    Total時間
    千回
    ----------
    方法
    千回
    ----------
    Total時間
    一万回
    ----------
    方法
    一万回
    ----------
    Total時間
    十万回
    ----------
    方法
    十万回
    ----------
    Total時間
    1 + Operator & System.String 0.1558 += Operator & System.String 4.0036 StringBuilder - Append 49.8517 StringBuilder - Append 531.7591
    2 += Operator & System.String 0.1572 + Operator & System.String 4.0159 StringBuilder - AppendFormat 54.4687 ArrayList - Add 570.7004
    3 -f Operator 0.1858 -f Operator 4.3914 ArrayList - Add 56.2569 StringBuilder - AppendFormat 577.2004
    4 System.String - Join 0.2566 Double Quotation囲み 4.7531 + Operator & System.String 447.2128 Write-Output CommandLet 45534.2396
    5 Double Quotation囲み 0.3189 ArrayList - Add 5.0609 += Operator & System.String 467.8290 + Operator & System.String 46428.2018
    6 -join Operator 0.4214 StringBuilder - Append 5.1494 -f Operator 566.3519 += Operator & System.String 49467.7897
    7 StringBuilder - Append 0.4616 StringBuilder - AppendFormat 5.4308 Double Quotation囲み 592.5740 Double Quotation囲み 56684.2068
    8 ArrayList - Add 0.4731 -join Operator 10.3588 Write-Output CommandLet 782.6930 -f Operator 68006.0728
    9 StringBuilder - AppendFormat 0.4841 System.String - Concat 13.1223 Join-Path CommandLet 1030.9394 Join-Path CommandLet 96968.5999
    10 System.String - Concat 0.7537 System.String - Join 14.0607 -join Operator 1090.3761 Join-String CommandLet 113846.2574
    11 += Operator & System.String[,] 0.7722 Write-Output CommandLet 24.5212 Join-String CommandLet 1617.8001 -join Operator 122103.0582
    12 + Operator & System.String[,] 0.7737 Join-Path CommandLet 33.6742 System.String - Join 2037.8914 System.String - Join 207792.2526
    13 + Operator & System.String[] 0.8166 Join-String CommandLet 41.1442 System.String - Concat 2039.2027 System.String - Concat 225004.4548
    14 += Operator & System.String[] 1.8272 + Operator & System.String[,] 63.0892 += Operator & System.String[] 6033.9105 + Operator & System.String[,] 797735.9162
    15 Write-Output CommandLet 2.4877 += Operator & System.String[] 63.2936 + Operator & System.String[,] 6178.6981 += Operator & System.String[] 825429.8791
    16 Join-Path CommandLet 2.6421 + Operator & System.String[] 63.4895 + Operator & System.String[] 6179.6757 + Operator & System.String[] 829149.9485
    17 Join-String CommandLet 3.0164 += Operator & System.String[,] 63.8305 += Operator & System.String[,] 6184.9431 += Operator & System.String[,] 840990.4387
  • 2回目の結果(計測時間の単位:ミリ秒)

    順位 百回
    ----------
    方法
    百回
    ----------
    Total時間
    千回
    ----------
    方法
    千回
    ----------
    Total時間
    一万回
    ----------
    方法
    一万回
    ----------
    Total時間
    十万回
    ----------
    方法
    十万回
    ----------
    Total時間
    1 += Operator & System.String 0.6655 -f Operator 4.5688 StringBuilder - Append 53.7023 StringBuilder - Append 531.6033
    2 -f Operator 0.6702 += Operator & System.String 4.7098 ArrayList - Add 54.2887 ArrayList - Add 571.6541
    3 Double Quotation囲み 0.8069 Double Quotation囲み 5.0990 StringBuilder - AppendFormat 61.3670 StringBuilder - AppendFormat 586.4022
    4 += Operator & System.String[] 1.3061 ArrayList - Add 5.4573 -f Operator 489.0656 + Operator & System.String 52067.1423
    5 -join Operator 1.3062 StringBuilder - Append 5.8264 += Operator & System.String 490.0746 -f Operator 54124.7900
    6 += Operator & System.String[,] 1.3215 StringBuilder - AppendFormat 6.1693 + Operator & System.String 507.5027 += Operator & System.String 54233.1379
    7 + Operator & System.String[] 1.8797 -join Operator 10.0667 Double Quotation囲み 510.4678 Double Quotation囲み 56607.1854
    8 + Operator & System.String[,] 1.9394 System.String - Concat 13.5308 Write-Output CommandLet 905.3599 Write-Output CommandLet 61875.2822
    9 System.String - Concat 3.1231 System.String - Join 13.5829 Join-Path CommandLet 1016.7767 Join-Path CommandLet 93663.0040
    10 StringBuilder - AppendFormat 3.1324 Write-Output CommandLet 26.1444 -join Operator 1111.6173 Join-String CommandLet 99401.6443
    11 System.String - Join 3.3221 + Operator & System.String 30.1410 System.String - Concat 1627.1417 -join Operator 100268.7897
    12 StringBuilder - Append 4.1588 Join-Path CommandLet 35.2685 Join-String CommandLet 1673.5181 System.String - Concat 196017.9893
    13 + Operator & System.String 4.3706 Join-String CommandLet 44.3687 System.String - Join 1894.9475 System.String - Join 216942.7133
    14 ArrayList - Add 6.9950 += Operator & System.String[,] 63.7410 += Operator & System.String[,] 6280.4282 + Operator & System.String[,] 807780.9007
    15 Join-String CommandLet 7.3213 + Operator & System.String[] 64.8512 += Operator & System.String[] 6412.8838 + Operator & System.String[] 824635.2317
    16 Write-Output CommandLet 11.3990 + Operator & System.String[,] 65.5948 + Operator & System.String[] 6414.0371 += Operator & System.String[] 850347.6100
    17 Join-Path CommandLet 29.5248 += Operator & System.String[] 66.0889 + Operator & System.String[,] 6530.4895 += Operator & System.String[,] 857871.1399
  • 3回目の結果(計測時間の単位:ミリ秒)

    順位 百回
    ----------
    方法
    百回
    ----------
    Total時間
    千回
    ----------
    方法
    千回
    ----------
    Total時間
    一万回
    ----------
    方法
    一万回
    ----------
    Total時間
    十万回
    ----------
    方法
    十万回
    ----------
    Total時間
    1 + Operator & System.String 0.1719 += Operator & System.String 3.9867 StringBuilder - Append 50.9141 StringBuilder - Append 532.3447
    2 += Operator & System.String 0.1756 + Operator & System.String 5.1583 ArrayList - Add 55.4117 ArrayList - Add 593.2931
    3 System.String - Concat 0.2531 Double Quotation囲み 5.2793 StringBuilder - AppendFormat 56.4219 StringBuilder - AppendFormat 605.7655
    4 -join Operator 0.3984 -f Operator 5.5600 += Operator & System.String 429.5863 + Operator & System.String 44518.1983
    5 StringBuilder - Append 0.4919 StringBuilder - Append 5.6009 Double Quotation囲み 444.7455 += Operator & System.String 51728.5216
    6 ArrayList - Add 0.5082 StringBuilder - AppendFormat 6.4505 -f Operator 477.1120 Double Quotation囲み 57533.0442
    7 StringBuilder - AppendFormat 0.6929 ArrayList - Add 6.8816 + Operator & System.String 545.6852 Write-Output CommandLet 57933.4316
    8 + Operator & System.String[] 0.7887 -join Operator 11.0932 Write-Output CommandLet 751.9841 -f Operator 59226.9510
    9 += Operator & System.String[] 0.8045 System.String - Concat 13.4884 Join-Path CommandLet 954.6884 Join-Path CommandLet 88974.3249
    10 += Operator & System.String[,] 0.8279 Write-Output CommandLet 25.3646 -join Operator 1008.1670 Join-String CommandLet 99453.8459
    11 + Operator & System.String[,] 0.8398 System.String - Join 26.5660 System.String - Join 1411.4798 -join Operator 100134.4948
    12 System.String - Join 0.9354 Join-Path CommandLet 33.6748 Join-String CommandLet 1463.1542 System.String - Concat 139916.4294
    13 Double Quotation囲み 0.9721 Join-String CommandLet 44.8396 System.String - Concat 1521.9248 System.String - Join 174617.3146
    14 -f Operator 0.9757 += Operator & System.String[] 64.1834 + Operator & System.String[,] 6191.9547 + Operator & System.String[] 790883.8929
    15 Write-Output CommandLet 2.0828 += Operator & System.String[,] 64.7171 += Operator & System.String[] 6254.4155 += Operator & System.String[,] 819732.1472
    16 Join-Path CommandLet 2.7309 + Operator & System.String[,] 65.1948 += Operator & System.String[,] 6323.0832 + Operator & System.String[,] 827918.5587
    17 Join-String CommandLet 3.6051 + Operator & System.String[] 65.9531 + Operator & System.String[] 6477.8440 += Operator & System.String[] 835149.1256

今回、得られた結果を分析すると繰り返し1,000回(千回)までは、どの方法でも誤差の範囲内である事がわかりました。

繰り返し回数が10,000回(一万回)以上になると、それぞれの結果で時間の開きがでてくることがわかります。
その中で 処理速度が速い方法 は、下記の3点でした。これ以外の方法は処理速度が遅く現実的な方法ではありません。

  • StringBuilderクラス - Appendメソッド
  • StringBuilderクラス - AppendFormatメソッド
  • ArrayListクラス - Addメソッド
実際の実行結果 < クリックで折りたたみが開く >

合計3回、検証したので結果をすべて掲載しようとしましたが、ここZenn.devの「本文のmarkdownには最大80000文字まで」という制限に引っかかってしまったので省略。

  • 実際の実行結果 - 1回目のみ掲載

    繰り返し回数:百回(100) < クリックで折りたたみが開く >
    Functionを実行 ループ回数:百回(100)
    PS C:\Users\"ユーザー名"> VerificationProcessingSpeed 100
    *=================================================================*
    
    * ループ回数:100 の検証 Start
    
    *=================================================================*
    
    
    演算子を使用した方法:
        「 + 」演算子を使用した方法 - データ型が通常の文字列(System.String)の場合:
    
    Name         Value
    ----         -----
    平均時間     0.001558
    Total時間 0.1558
    
        「 + 」演算子を使用した方法 - データ型が多段階配列(ジャグ配列)の文字列配列(System.String[])の場合:
    
    Name         Value
    ----         -----
    平均時間     0.008166
    Total時間 0.8166
    
        「 + 」演算子を使用した方法 - データ型が多次元配列の文字列配列(System.String[,])の場合:
    
    Name         Value
    ----         -----
    平均時間     0.007737
    Total時間 0.7737
    
        「 += 」演算子を使用した方法 - データ型が通常の文字列(System.String)の場合:
    
    Name         Value
    ----         -----
    平均時間     0.001572
    Total時間 0.1572
    
        「 += 」演算子を使用した方法 - データ型が多段階配列(ジャグ配列)の文字列配列(System.String[])の場合:
    
    Name         Value
    ----         -----
    平均時間     0.018272
    Total時間 1.8272
    
        「 += 」演算子を使用した方法 - データ型が多次元配列の文字列配列(System.String[,])の場合:
    
    Name         Value
    ----         -----
    平均時間     0.007722
    Total時間 0.7722
    
        「 -f 」演算子を使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.001858
    Total時間 0.1858
    
        「 -join 」演算子を使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.004214
    Total時間 0.4214
    
    メソッド・コマンドを使用した方法:
        ArrayListの「 Add 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.004731
    Total時間 0.4731
    
        StringBuilderの「 Append 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.004616
    Total時間 0.4616
    
        StringBuilderの「 AppendFormat 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.004841
    Total時間 0.4841
    
        System.Stringの「 Concat 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.007537
    Total時間 0.7537
    
        System.Stringの「 Join 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.002566
    Total時間 0.2566
    
        Join-Stringコマンドレットを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.030164
    Total時間 3.0164
    
        Write-Outputコマンドレットを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.024877
    Total時間 2.4877
    
        ダブルコーテーション("")を使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.003189
    Total時間 0.3189
    
        Join-Pathコマンドレットを使用した方法(限定的な状況で使用):
    
    Name         Value
    ----         -----
    平均時間     0.026421
    Total時間 2.6421
    
    *-----------------------------------------------------------------*
    
    Name                            Value
    ----                            -----
    Join-Path CommandLet            {[平均時間, 0.026421], [Total時間, 2.6421]}
    System.String - Join            {[平均時間, 0.002566], [Total時間, 0.2566]}
    StringBuilder - Append          {[平均時間, 0.004616], [Total時間, 0.4616]}
    += Operator & System.String[,] {[平均時間, 0.007722], [Total時間, 0.7722]}
    StringBuilder - AppendFormat    {[平均時間, 0.004841], [Total時間, 0.4841]}
    + Operator & System.String[,]  {[平均時間, 0.007737000000000001], [Total時間, 0.7737]}
    -f Operator                     {[平均時間, 0.0018579999999999998], [Total時間, 0.1858]}
    + Operator & System.String[]   {[平均時間, 0.008166], [Total時間, 0.8166]}
    Join-String CommandLet          {[平均時間, 0.030164], [Total時間, 3.0164]}
    + Operator & System.String     {[平均時間, 0.001558], [Total時間, 0.1558]}
    Double Quotation囲み            {[平均時間, 0.003189], [Total時間, 0.3189]}
    += Operator & System.String[]  {[平均時間, 0.018272], [Total時間, 1.8272]}
    -join Operator                  {[平均時間, 0.004214], [Total時間, 0.4214]}
    ArrayList - Add                 {[平均時間, 0.004731], [Total時間, 0.4731]}
    Write-Output CommandLet         {[平均時間, 0.024876999999999996], [Total時間, 2.4877]}
    System.String - Concat          {[平均時間, 0.007537], [Total時間, 0.7537]}
    += Operator & System.String    {[平均時間, 0.001572], [Total時間, 0.1572]}
    
    
    *=================================================================*
    
    * ループ回数:100 の検証 End
    
    *=================================================================*
    
    
    PS C:\Users\"ユーザー名">
    
    繰り返し回数:千回(1,000) < クリックで折りたたみが開く >
    Functionを実行 ループ回数:千回(1,000)
    PS C:\Users\"ユーザー名"> VerificationProcessingSpeed 1000
    *=================================================================*
    
    * ループ回数:1000 の検証 Start
    
    *=================================================================*
    
    
    演算子を使用した方法:
        「 + 」演算子を使用した方法 - データ型が通常の文字列(System.String)の場合:
    
    Name         Value
    ----         -----
    平均時間     0.0040159
    Total時間 4.0159
    
        「 + 」演算子を使用した方法 - データ型が多段階配列(ジャグ配列)の文字列配列(System.String[])の場合:
    
    Name         Value
    ----         -----
    平均時間     0.0634895
    Total時間 63.4895
    
        「 + 」演算子を使用した方法 - データ型が多次元配列の文字列配列(System.String[,])の場合:
    
    Name         Value
    ----         -----
    平均時間     0.0630892
    Total時間 63.0892
    
        「 += 」演算子を使用した方法 - データ型が通常の文字列(System.String)の場合:
    
    Name         Value
    ----         -----
    平均時間     0.0040036
    Total時間 4.0036
    
        「 += 」演算子を使用した方法 - データ型が多段階配列(ジャグ配列)の文字列配列(System.String[])の場合:
    
    Name         Value
    ----         -----
    平均時間     0.0632936
    Total時間 63.2936
    
        「 += 」演算子を使用した方法 - データ型が多次元配列の文字列配列(System.String[,])の場合:
    
    Name         Value
    ----         -----
    平均時間     0.0638305
    Total時間 63.8305
    
        「 -f 」演算子を使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.0043914
    Total時間 4.3914
    
        「 -join 」演算子を使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.0103588
    Total時間 10.3588
    
    メソッド・コマンドを使用した方法:
        ArrayListの「 Add 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.0050609
    Total時間 5.0609
    
        StringBuilderの「 Append 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.0051494
    Total時間 5.1494
    
        StringBuilderの「 AppendFormat 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.0054308
    Total時間 5.4308
    
        System.Stringの「 Concat 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.0131223
    Total時間 13.1223
    
        System.Stringの「 Join 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.0140607
    Total時間 14.0607
    
        Join-Stringコマンドレットを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.0411442
    Total時間 41.1442
    
        Write-Outputコマンドレットを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.0245212
    Total時間 24.5212
    
        ダブルコーテーション("")を使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.0047531
    Total時間 4.7531
    
        Join-Pathコマンドレットを使用した方法(限定的な状況で使用):
    
    Name         Value
    ----         -----
    平均時間     0.0336742
    Total時間 33.6742
    
    *-----------------------------------------------------------------*
    
    Name                            Value
    ----                            -----
    Join-Path CommandLet            {[平均時間, 0.0336742], [Total時間, 33.6742]}
    System.String - Join            {[平均時間, 0.0140607], [Total時間, 14.0607]}
    StringBuilder - Append          {[平均時間, 0.0051494], [Total時間, 5.1494]}
    += Operator & System.String[,] {[平均時間, 0.0638305], [Total時間, 63.8305]}
    StringBuilder - AppendFormat    {[平均時間, 0.0054307999999999995], [Total時間, 5.4308]}
    + Operator & System.String[,]  {[平均時間, 0.0630892], [Total時間, 63.0892]}
    -f Operator                     {[平均時間, 0.0043914], [Total時間, 4.3914]}
    + Operator & System.String[]   {[平均時間, 0.0634895], [Total時間, 63.4895]}
    Join-String CommandLet          {[平均時間, 0.0411442], [Total時間, 41.1442]}
    + Operator & System.String     {[平均時間, 0.0040159], [Total時間, 4.0159]}
    Double Quotation囲み            {[平均時間, 0.0047531], [Total時間, 4.7531]}
    += Operator & System.String[]  {[平均時間, 0.06329359999999999], [Total時間, 63.2936]}
    -join Operator                  {[平均時間, 0.0103588], [Total時間, 10.3588]}
    ArrayList - Add                 {[平均時間, 0.0050609], [Total時間, 5.0609]}
    Write-Output CommandLet         {[平均時間, 0.0245212], [Total時間, 24.5212]}
    System.String - Concat          {[平均時間, 0.0131223], [Total時間, 13.1223]}
    += Operator & System.String    {[平均時間, 0.0040035999999999995], [Total時間, 4.0036]}
    
    
    *=================================================================*
    
    * ループ回数:1000 の検証 End
    
    *=================================================================*
    
    
    PS C:\Users\"ユーザー名">
    
    繰り返し回数:1万回(10,000) < クリックで折りたたみが開く >
    Functionを実行 ループ回数:1万回(10,000)
    PS C:\Users\"ユーザー名"> VerificationProcessingSpeed 10000
    *=================================================================*
    
    * ループ回数:10000 の検証 Start
    
    *=================================================================*
    
    
    演算子を使用した方法:
        「 + 」演算子を使用した方法 - データ型が通常の文字列(System.String)の場合:
    
    Name         Value
    ----         -----
    平均時間     0.04472128
    Total時間 447.2128
    
        「 + 」演算子を使用した方法 - データ型が多段階配列(ジャグ配列)の文字列配列(System.String[])の場合:
    
    Name         Value
    ----         -----
    平均時間     0.61796757
    Total時間 6179.6757
    
        「 + 」演算子を使用した方法 - データ型が多次元配列の文字列配列(System.String[,])の場合:
    
    Name         Value
    ----         -----
    平均時間     0.61786981
    Total時間 6178.6981
    
        「 += 」演算子を使用した方法 - データ型が通常の文字列(System.String)の場合:
    
    Name         Value
    ----         -----
    平均時間     0.0467829
    Total時間 467.829
    
        「 += 」演算子を使用した方法 - データ型が多段階配列(ジャグ配列)の文字列配列(System.String[])の場合:
    
    Name         Value
    ----         -----
    平均時間     0.60339105
    Total時間 6033.9105
    
        「 += 」演算子を使用した方法 - データ型が多次元配列の文字列配列(System.String[,])の場合:
    
    Name         Value
    ----         -----
    平均時間     0.61849431
    Total時間 6184.9431
    
        「 -f 」演算子を使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.05663519
    Total時間 566.3519
    
        「 -join 」演算子を使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.10903761
    Total時間 1090.3761
    
    メソッド・コマンドを使用した方法:
        ArrayListの「 Add 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.00562569
    Total時間 56.2569
    
        StringBuilderの「 Append 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.00498517
    Total時間 49.8517
    
        StringBuilderの「 AppendFormat 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.00544687
    Total時間 54.4687
    
        System.Stringの「 Concat 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.20392027
    Total時間 2039.2027
    
        System.Stringの「 Join 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.20378914
    Total時間 2037.8914
    
        Join-Stringコマンドレットを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.16178001
    Total時間 1617.8001
    
        Write-Outputコマンドレットを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.0782693
    Total時間 782.693
    
        ダブルコーテーション("")を使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.0592574
    Total時間 592.574
    
        Join-Pathコマンドレットを使用した方法(限定的な状況で使用):
    
    Name         Value
    ----         -----
    平均時間     0.10309394
    Total時間 1030.9394
    
    *-----------------------------------------------------------------*
    
    Name                            Value
    ----                            -----
    Join-Path CommandLet            {[平均時間, 0.10309394], [Total時間, 1030.9394]}
    System.String - Join            {[平均時間, 0.20378914], [Total時間, 2037.8914]}
    StringBuilder - Append          {[平均時間, 0.00498517], [Total時間, 49.8517]}
    += Operator & System.String[,] {[平均時間, 0.61849431], [Total時間, 6184.9431]}
    StringBuilder - AppendFormat    {[平均時間, 0.0054468699999999995], [Total時間, 54.4687]}
    + Operator & System.String[,]  {[平均時間, 0.61786981], [Total時間, 6178.6981]}
    -f Operator                     {[平均時間, 0.05663519], [Total時間, 566.3519]}
    + Operator & System.String[]   {[平均時間, 0.61796757], [Total時間, 6179.6757]}
    Join-String CommandLet          {[平均時間, 0.16178001], [Total時間, 1617.8001]}
    + Operator & System.String     {[平均時間, 0.04472128], [Total時間, 447.2128]}
    Double Quotation囲み            {[平均時間, 0.059257399999999995], [Total時間, 592.574]}
    += Operator & System.String[]  {[平均時間, 0.60339105], [Total時間, 6033.9105]}
    -join Operator                  {[平均時間, 0.10903761], [Total時間, 1090.3761]}
    ArrayList - Add                 {[平均時間, 0.00562569], [Total時間, 56.2569]}
    Write-Output CommandLet         {[平均時間, 0.0782693], [Total時間, 782.693]}
    System.String - Concat          {[平均時間, 0.20392027000000001], [Total時間, 2039.2027]}
    += Operator & System.String    {[平均時間, 0.0467829], [Total時間, 467.829]}
    
    
    *=================================================================*
    
    * ループ回数:10000 の検証 End
    
    *=================================================================*
    
    
    PS C:\Users\"ユーザー名">
    
    繰り返し回数:10万回(100,000) < クリックで折りたたみが開く >
    Functionを実行 ループ回数:10万回(100,000)
    PS C:\Users\"ユーザー名"> VerificationProcessingSpeed 100000
    *=================================================================*
    
    * ループ回数:100000 の検証 Start
    
    *=================================================================*
    
    
    演算子を使用した方法:
        「 + 」演算子を使用した方法 - データ型が通常の文字列(System.String)の場合:
    
    Name         Value
    ----         -----
    平均時間     0.464282018
    Total時間 46428.2018
    
        「 + 」演算子を使用した方法 - データ型が多段階配列(ジャグ配列)の文字列配列(System.String[])の場合:
    
    Name         Value
    ----         -----
    平均時間     8.291499485
    Total時間 829149.9485
    
        「 + 」演算子を使用した方法 - データ型が多次元配列の文字列配列(System.String[,])の場合:
    
    Name         Value
    ----         -----
    平均時間     7.977359162
    Total時間 797735.9162
    
        「 += 」演算子を使用した方法 - データ型が通常の文字列(System.String)の場合:
    
    Name         Value
    ----         -----
    平均時間     0.494677897
    Total時間 49467.7897
    
        「 += 」演算子を使用した方法 - データ型が多段階配列(ジャグ配列)の文字列配列(System.String[])の場合:
    
    Name         Value
    ----         -----
    平均時間     8.254298791
    Total時間 825429.8791
    
        「 += 」演算子を使用した方法 - データ型が多次元配列の文字列配列(System.String[,])の場合:
    
    Name         Value
    ----         -----
    平均時間     8.409904387
    Total時間 840990.4387
    
        「 -f 」演算子を使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.680060728
    Total時間 68006.0728
    
        「 -join 」演算子を使用した方法:
    
    Name         Value
    ----         -----
    平均時間     1.221030582
    Total時間 122103.0582
    
    メソッド・コマンドを使用した方法:
        ArrayListの「 Add 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.005707004
    Total時間 570.7004
    
        StringBuilderの「 Append 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.005317591
    Total時間 531.7591
    
        StringBuilderの「 AppendFormat 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.005772004
    Total時間 577.2004
    
        System.Stringの「 Concat 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     2.250044548
    Total時間 225004.4548
    
        System.Stringの「 Join 」メソッドを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     2.077922526
    Total時間 207792.2526
    
        Join-Stringコマンドレットを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     1.138462574
    Total時間 113846.2574
    
        Write-Outputコマンドレットを使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.455342396
    Total時間 45534.2396
    
        ダブルコーテーション("")を使用した方法:
    
    Name         Value
    ----         -----
    平均時間     0.566842068
    Total時間 56684.2068
    
        Join-Pathコマンドレットを使用した方法(限定的な状況で使用):
    
    Name         Value
    ----         -----
    平均時間     0.969685999
    Total時間 96968.5999
    
    *-----------------------------------------------------------------*
    
    Name                            Value
    ----                            -----
    Join-Path CommandLet            {[平均時間, 0.969685999], [Total時間, 96968.5999]}
    System.String - Join            {[平均時間, 2.077922526], [Total時間, 207792.2526]}
    StringBuilder - Append          {[平均時間, 0.005317591], [Total時間, 531.7591]}
    += Operator & System.String[,] {[平均時間, 8.409904387000001], [Total時間, 840990.4387]}
    StringBuilder - AppendFormat    {[平均時間, 0.005772004], [Total時間, 577.2004]}
    + Operator & System.String[,]  {[平均時間, 7.977359162], [Total時間, 797735.9162]}
    -f Operator                     {[平均時間, 0.680060728], [Total時間, 68006.0728]}
    + Operator & System.String[]   {[平均時間, 8.291499485000001], [Total時間, 829149.9485]}
    Join-String CommandLet          {[平均時間, 1.138462574], [Total時間, 113846.2574]}
    + Operator & System.String     {[平均時間, 0.464282018], [Total時間, 46428.2018]}
    Double Quotation囲み            {[平均時間, 0.566842068], [Total時間, 56684.2068]}
    += Operator & System.String[]  {[平均時間, 8.254298791], [Total時間, 825429.8791]}
    -join Operator                  {[平均時間, 1.221030582], [Total時間, 122103.0582]}
    ArrayList - Add                 {[平均時間, 0.005707003999999999], [Total時間, 570.7004]}
    Write-Output CommandLet         {[平均時間, 0.455342396], [Total時間, 45534.2396]}
    System.String - Concat          {[平均時間, 2.250044548], [Total時間, 225004.4548]}
    += Operator & System.String    {[平均時間, 0.49467789700000003], [Total時間, 49467.7897]}
    
    
    *=================================================================*
    
    * ループ回数:100000 の検証 End
    
    *=================================================================*
    PS C:\Users\"ユーザー名">
    

まとめ

  • PowerShellにおける文字列の結合方法は大きくわけると13種類あった

  • 使用用途べつにわけると

    • 結合する文字列の数が少ない & 処理速度が重要視されない場合
      1. 「 + 」演算子
      2. 「 -f 」演算子
    • 結合する文字列の数が多い & 処理速度を重要視する場合
      1. StringBuilderクラスの「 Append 」メソッド
      2. StringBuilderクラスの「 AppendFormat 」メソッド
      3. ArrayListクラスの「 Add 」メソッド
    • 文字列配列を結合する場合
      1. 「 -join 」演算子
      2. System.Stringクラスの「 Join 」メソッド
    • 結合する文字列がパスの場合
      1. 「 Join-Path 」コマンドレット
  • 処理速度で考慮すると
    結果を要約すると繰り返し1,000回(千回)までは、どの方法でも誤差の範囲内である事がわかりました。

    繰り返し回数が10,000回(一万回)以上になると下記の3点の内いずれかを選択した方が良い

    • StringBuilderクラス - Appendメソッド
    • StringBuilderクラス - AppendFormatメソッド
    • ArrayListクラス - Addメソッド

前述しているとおり、環境やコード、結合するデータによっても大きく変動すると思います。
今回の検証結果は、あくまでも参考程度に受け取って頂ければと思います。

今回テーマにしていた

  • PowerShellスクリプトで小規模のツールを作成するときは「必ずしもStringBuilderクラスを使用しなくても良いのか。」

に関する私の見解は、もう少し気軽に 「 + 」演算子「 -f 」演算子 を使っていこうと思いました。

関連記事

https://haretokidoki-blog.com/pasocon_powershell-startup/
https://zenn.dev/haretokidoki/articles/7e6924ff0cc960

GitHubで編集を提案

Discussion