プレビューと候補リリースでパフォーマンスに違いはあるか

PowerShell 7.0.0 RC3までは公開されたものの、正式版の公開まではあと1、2カ月かかりそうな感じだ。せっかくプレビューが6個、候補リリースが3個公開されているので、その過程でPowerShell 7のパフォーマンスに変化があったのかどうか、調べてみようと思う。

MicrosoftはPowerShell 7.0.0-Preview1を公開したときに「大幅にパフォーマンスが向上した」と喧伝していた。これはベースとしている.NET Coreのバージョンが上がったためで、.NET Coreのパフォーマンスが向上したので、それを使用しているPowerShell 7の性能も向上した、という理屈になっていた。試した限りではWindowsではうたい文句どおりの効果が見られ、LinuxとmacOSでは微妙、または逆に遅くなったといった結果が得られていた。

はたしてプレビューおよび候補リリースの間にパフォーマンスに変化があったのか、実測値から見ていこう。

ベンチマーク

PowerShellそのものの性能を計測する包括的なベンチマークというのは筆者が知る限り存在しないので、ここではこれまでに本連載でも数回使用したことのある次のマイクロベンチマークを使用する。

【Group-Objectベンチ】

Measure-Command { 1..100000 | % {Get-Random -Minimum 1 -Maximum 10000} | Group-Object }

【Sort-Objectベンチ】

Measure-Command { 1..100000 | % {Get-Random -Minimum 1 -Maximum 10000} | Sort-Object }

【Import-Csvベンチ】

Measure-Command {$a = Import-Csv -Header '1','2','3','4','5','6','7','8','9','10','11','12','13','14','15' KEN_ALL-UTF8.CSV}

このうちImport-Csvベンチでは、CSVファイルをデータとして使用する。ここでは「読み仮名データの促音・拗音を小書きで表記しないもの - zip形式 日本郵便 」で公開されている「全国一括 (1,689,684 Byte)」をダウンロードしてきて、エンコーディングをUTF-8に変更したものを使った。ファイル名は「KEN_ALL-UTF8.CSV」だ。

# head KEN_ALL-UTF8.CSV
01101,"060  ","0600000","ホツカイドウ","サツポロシチユウオウク","イカニケイサイガナイバアイ","北海道","札幌市中央区","以下に掲載がない場合",0,0,0,0,0,0
01101,"064  ","0640941","ホツカイドウ","サツポロシチユウオウク","アサヒガオカ","北海道","札幌市中央区","旭ケ丘",0,0,1,0,0,0
01101,"060  ","0600041","ホツカイドウ","サツポロシチユウオウク","オオドオリヒガシ","北海道","札幌市中央区","大通東",0,0,1,0,0,0
01101,"060  ","0600042","ホツカイドウ","サツポロシチユウオウク","オオドオリニシ(1-19チヨウメ)","北海道","札幌市中央区","大通西(1〜19丁目)",1,0,1,0,0,0
01101,"064  ","0640820","ホツカイドウ","サツポロシチユウオウク","オオドオリニシ(20-28チヨウメ)","北海道","札幌市中央区","大通西(20〜28丁目)",1,0,1,0,0,0
01101,"060  ","0600031","ホツカイドウ","サツポロシチユウオウク","キタ1ジヨウヒガシ","北海道","札幌市中央区","北一条東",0,0,1,0,0,0
01101,"060  ","0600001","ホツカイドウ","サツポロシチユウオウク","キタ1ジヨウニシ(1-19チヨウメ)","北海道","札幌市中央区","北一条西(1〜19丁目)",1,0,1,0,0,0
01101,"064  ","0640821","ホツカイドウ","サツポロシチユウオウク","キタ1ジヨウニシ(20-28チヨウメ)","北海道","札幌市中央区","北一条西(20〜28丁目)",1,0,1,0,0,0
01101,"060  ","0600032","ホツカイドウ","サツポロシチユウオウク","キタ2ジヨウヒガシ","北海道","札幌市中央区","北二条東",0,0,1,0,0,0
01101,"060  ","0600002","ホツカイドウ","サツポロシチユウオウク","キタ2ジヨウニシ(1-19チヨウメ)","北海道","札幌市中央区","北二条西(1〜19丁目)",1,0,1,0,0,0
#

上記コマンドを実行すると次のような結果を得ることができる。

Group-Objectベンチ実行結果サンプル

Sort-Objectベンチ実行結果サンプル

Import-Csvベンチ実行結果

ただし、ここで取り上げたマイクロベンチマークはあくまでもPowerShellの1つの側面を示すものでしかない。PowerShellはそもそも実行時間のばらつきが大きい傾向にある。同じ処理でもかかる時間の振れ幅が大きいのだ。そのため、今回紹介するベンチマークは、あくまでも参考程度のものだと考えておいてほしい。

さらに説明すると、PowerShellはそもそもシェルそのものの処理性能を期待するタイプのプラットフォームではない。PowerShellはUNIX系のシェルのように処理の高速性や並列性を期待することがかなり難しい。PowerShellそのもので高速な処理を実現するとか、そういった類のツールではないということは理解しておこう。

ベンチマーク結果

筆者がWindows 10でPowerShell 7.0.0 Preview1からRC3まで実施したマイクロベンチマークの結果は次の通りだ。それほど難しいベンチマークではないので、同じ処理を行って各自比較を行ってもらえればと思う。

Windows 10 Group-Object Sort-Object Import-Csv
pre1 5.054 4.900 4.551
pre2 4.677 4.290 4.591
pre3 5.353 5.029 4.028
pre4 5.275 4.867 3.927
pre5 5.233 4.834 3.967
pre6 6.129 5.656 4.441
rc1 5.450 4.830 4.179
rc2 5.346 5.053 4.238
rc3 5.541 5.120 4.437

結果をグラフにまとめると次のようになる。

棒グラフにまとめた例

折れ線グラフにまとめた例

ベンチマーク種類ごとに棒グラフにまとめた例

Preview.3からちょっとだけモッサリしてきたかなという感じはあるものの、特にこれといった変動の傾向はないように思う。手元で実行してもらえればわかると思うが、PowerShellは実行時間が結構大きく変動する。振れ幅が大きいので、上記グラフくらいの変動だと結構誤差の範囲内のようだ。

PowerShellの提供する機能は.NET Coreの実装に依存するところが大きい。コマンドレットごとにパフォーマンスの改善はあったとしても、全体としての性能は.NET Coreの性能に依存しており、プレビューや候補リリースごとに全体としての大きな変動はないようだ。今後も似たような状態であることが推測されるので、.NET Coreの新しいバージョンに移ったときに、全体のパフォーマンスにも影響が出てくるものと見られ、それ以外では大きな変化はないのではないかと考えられる。