更新履歴(3件・最終更新 2026年08月02日)
この記事に加えた変更の記録です。アーカイブした更新前のバージョンは、DOI付きの固定URLから読めます。
- 記事の冒頭に「この記事の知識マップ」節を追加しました。本文で扱っている概念とその関係を、要約・図・詳細ページへのリンクにまとめたものです。本文の主張は変えていません。
- 外部レビュー(1283件)への対応として本文を更新しました。個々の変更内容は、この下の履歴を参照してください。
- 比喩や口語で書かれていた6か所を技術的な記述に置き換えました。電源モードのオーバーレイと電源プランの2層構造を図にし、公開されている`powercfg`のオプションにオーバーレイの切り替えが無いことを明記しました。用語表、測定を何回まわすかの目安、固定する・実行する・記録する・解釈するのチェックリストを追加しました。
- 初版公開
この記事を引用する(DOI: 10.5281/zenodo.21589656)
この記事はZenodoにアーカイブされています。常に最新版へ解決されるDOIと、いま表示している版に固定されたDOIの両方を下に示します。
小村 豪(2026)「Windowsでプログラムのバージョン別速度を正しく比較する方法」合同会社小村ソフト. https://doi.org/10.5281/zenodo.21589656 https://staging.comcomponent.com/blog/2026/03/16/002-windows-benchmark-comparing-program-versions/
- DOI(最新版)
- 10.5281/zenodo.21589656
- DOI(この版)
- 10.5281/zenodo.21732683
Windows でプログラムのバージョン A と B を比較したい。 そのとき一番やってはいけないのは、同じマシンで 1 回ずつ実行して「B のほうが 8% 速いっぽい」と言ってしまうことです。
その 8% は、本当にコード差かもしれません。 でも実際には、電源モード、power plan、熱、バックグラウンド更新、検索インデックス、ウイルススキャン、アフィニティ、実行順序、キャッシュ状態のどれかだった、というのが Windows ベンチマークでよくある話です。条件を 1 つずつ潰していく地味な作業になります。
この記事では、Windows 上で異なるバージョンのプログラムの実行速度を、できるだけコード差に近い形で比較する方法をまとめます。
対象は主に Windows 11 を想定していますが、powercfg や start などの大半は Windows 10 でも同様に使えます。
先に押さえておく用語
本文には英語のまま出てくる用語があります。初出でつまずかないよう、先にまとめておきます。
| 用語 | 意味 |
|---|---|
| ETW | Event Tracing for Windows。Windows に標準で入っているトレース基盤です。OS やドライバー、アプリが出すイベントをまとめて記録できます |
| WPR / WPA | Windows Performance Recorder と Windows Performance Analyzer。ETW のトレースを記録するツールと、それを開いて分析するツールで、どちらも Windows ADK に含まれます |
| clean boot | Microsoft 以外のサービスとスタートアップ アプリを止めて、最小構成で起動する手順です。常駐アプリのノイズを減らす目的で使います |
| PGO | Profile-Guided Optimization。一度実行して集めた分岐や呼び出しの統計を、次のビルドの最適化判断に使う仕組みです。ビルド条件が変わるので、比較対象がそろっているかの確認項目になります |
| p95 / p99 | パーセンタイル。全 run を速い順に並べたとき、下から 95% / 99% の位置にある値です。「20 回に 1 回はこれより遅い」が p95 にあたります |
| NUMA | Non-Uniform Memory Access。CPU から見てメモリまでの距離が均一でない構成です。どのノードで実行されるかで、メモリアクセスの速度が変わります |
| コア駐車(core parking) | 負荷が低いときに、使わない論理プロセッサを寝かせておく電力管理の仕組みです |
まず結論
再現性を上げるコツは、突き詰めると次の 6 つです。
-
「何を比較したいか」を先に決める コード差を見たいのか、実ユーザー体験を見たいのかで、揃えるべき環境が変わります。
-
power mode と power plan を別物として記録する Windows ではここを雑に扱うと、比較が OS の省電力方針比較になりがちです。
-
冷えた 1 回目と、温まった後の定常状態を分ける 初回だけ速い・後半だけ遅い、は珍しくありません。
-
A→B→A→B のように交互に回す A を先に全部回してから B を回すと、熱やバックグラウンド状態の偏りを食らいます。
-
平均だけでなく中央値とばらつきを見る 1 個の外れ値で世界観が壊れます。平均は思ったより脆いです。
-
差が小さいなら ETW / WPR で原因まで掘る 体感だけで議論すると、どちらの主張も裏づけがないまま平行線になります。
この記事の知識マップ
この記事は、Windows上でプログラムのバージョン間の速度を比較する際の再現性をテーマに、Power mode(オーバーレイ)とPower planという2層の電源設定を固定・記録することが前提になることを示す。Power modeの違いはコア駐車などPPMの挙動を左右し、Modern Standby対応デバイスではPower planの選択肢自体がBalanced系に制限される。検索インデックスやDefenderのスキャン、通知といったバックグラウンド処理は測定値のブレの原因になり得るため、除外設定やクリーンブート、通知の抑制で軽減する。Wall-clock time・CPU time・Cycle countをQueryPerformanceCounter・GetProcessTimes・QueryProcessCycleTimeでそれぞれ計測し、差が小さく理由が読めない場合はWPRでETWトレースを取りWPAで比較することが推奨される。
flowchart LR
accTitle: Windowsベンチマーク比較の再現性の知識マップ
accDescr: Power modeとPower planという2層の電源設定を固定・記録することがベンチマークの再現性の前提になること、検索インデックスやDefenderスキャンなどのバックグラウンド処理が測定値のブレを生み除外設定やクリーンブートで軽減できること、Wall-clock time・CPU time・Cycle countをそれぞれ専用APIで計測すること、差が小さいときにWPRとWPAで原因を掘り下げる流れを示す図
benchmark_reproducibility["ベンチマークの再現性"]
power_mode["電源モード/電源プラン(PPM)"]
power_plan["Power plan(電源プラン)"]
powercfg["powercfg"]
modern_standby["Modern Standby対応デバイス"]
core_parking["Core Parking"]
search_indexing["検索インデックス作成"]
benchmark_result_variance["ベンチマーク結果のばらつき(ブレ)"]
exclusion_setting["除外設定(フォルダー除外)"]
clean_boot["クリーンブート(clean boot)"]
do_not_disturb["Do not disturb(通知の抑制)"]
wpr["Windows Performance Recorder(WPR)"]
etw["ETW(Event Tracing for Windows)"]
wpa["Windows Performance Analyzer(WPA)"]
inconclusive_benchmark_result["差が小さい・理由が読めないベンチマーク結果"]
wall_clock_time["Wall-clock time(実時間)"]
queryperformancecounter["QueryPerformanceCounter(QPC)"]
cpu_time["CPU time(ユーザー+カーネル時間)"]
getprocesstimes["GetProcessTimes"]
cycle_count["Cycle count(CPUサイクル数)"]
queryprocesscycletime["QueryProcessCycleTime"]
process_priority["優先度クラス(priority class)"]
start_command["startコマンド"]
processor_affinity["プロセッサアフィニティ(affinity mask)"]
processor_groups["プロセッサグループ(Processor Groups)"]
benchmark_reproducibility -->|"前提とする"| power_mode
benchmark_reproducibility -->|"前提とする"| power_plan
power_plan -->|"で構成できる"| powercfg
modern_standby -.->|"両立しない"| power_plan
core_parking -.->|"で構成できる"| power_mode
search_indexing -.->|"原因になり得る"| benchmark_result_variance
exclusion_setting -.->|"軽減する"| benchmark_result_variance
clean_boot -->|"軽減する"| benchmark_result_variance
do_not_disturb -.->|"軽減する"| benchmark_result_variance
wpr -->|"利用する"| etw
wpa -->|"利用する"| etw
wpa -.->|"前提とする"| wpr
wpr -->|"推奨される対応"| inconclusive_benchmark_result
wall_clock_time -->|"で確認できる"| queryperformancecounter
cpu_time -->|"で確認できる"| getprocesstimes
cycle_count -->|"で確認できる"| queryprocesscycletime
process_priority -->|"で構成できる"| start_command
processor_affinity -->|"で構成できる"| start_command
processor_affinity -.->|"前提とする"| processor_groups
benchmark_reproducibility -.->|"利用する"| wall_clock_time
benchmark_reproducibility -.->|"利用する"| cpu_time
benchmark_reproducibility -.->|"利用する"| cycle_count
benchmark_result_variance -->|"両立しない"| benchmark_reproducibility
benchmark_reproducibility -.->|"原因になり得る"| inconclusive_benchmark_result
benchmark_reproducibility -.->|"利用する"| start_command
図の実線は常に成り立つ関係、破線は条件付きの関係です(成立条件は詳細ページの各関係の説明に記載)。関係すべての一覧(全25件、根拠・確度つき)と主要概念の定義は知識マップ詳細ページにまとめています。データ: JSON-LD / Turtle
何を比較したいのかを最初に決める
「速度比較」と一口に言っても、実は 2 種類あります。
1. コード差を見たい比較
アルゴリズム変更、データ構造変更、コンパイラ最適化、ランタイム更新などによって、実装そのものが速くなったかを知りたい比較です。
この場合は、環境ノイズをできるだけ削ります。 ベンチ専用セッション、power mode 固定、通知停止、検索インデックスや同期の抑制、必要なら clean boot までやります。
2. 実ユーザー体験を見たい比較
配布後にユーザーが普段の Windows 上で体感する速さを知りたい比較です。
この場合は、現実に存在するノイズを全部消してはいけません。 OneDrive 同期、Defender、通知、通常の電源設定などを含んだ「それっぽい日常環境」で比較したほうが、現実に近い結果になります。
この 2 つを混ぜると、結論がねじれます。 「ラボでは 12% 速いのに、現実では誤差」「現実では速いのに、CPU 時間では変わらない」みたいなことが普通に起きます。
Windows で結果がぶれる主因
まず、何が結果をぶらすのかを雑に一覧化しておきます。
| 層 | ぶれ要因 | 典型例 |
|---|---|---|
| ハードウェア | CPU / GPU、メモリ、SSD、冷却 | ノート PC の薄さ、冷却台の有無 |
| ファームウェア | BIOS / UEFI、OEM 制御 | 省電力ポリシー、ファン制御 |
| OS | Windows build、ドライバ、更新状態 | 同じ PC でも更新後に挙動が変わる |
| 電源 | AC / DC、power mode、power plan | バッテリー駆動だと別世界 |
| 熱 | 室温、ファン、直前の負荷 | 1 回目だけターボ、後半で失速 |
| バックグラウンド | Update、Defender、同期、通知 | 実行中にスキャンや同期が走る |
| スケジューリング | 優先度、アフィニティ、NUMA | マシン次第で CPU 配置が変わる |
| データ / キャッシュ | OS キャッシュ、アプリキャッシュ | 初回だけ遅い、2 回目以降だけ速い |
| ビルド条件 | Debug / Release、PGO、ログ有無 | そもそも別物を比べている |
要するに、「同じ Windows マシン」でも、条件が揃っていなければ別の実験です。
power mode と power plan は分けて考える
ここはかなり重要です。
Windows には、設定アプリの Power mode と、従来の Power plan(powercfg で見える電源プラン)がいます。
見た目が似ているので一緒くたにされがちですが、雑に扱うと比較がぐちゃっとします。
Windows の設定アプリでは、Settings > System > Power & battery から Power mode を選べます。
Microsoft のドキュメントでは、Plugged in / On Battery ごとに Best power efficiency、Balanced、Best performance を切り替えられるとされています。さらに、Power mode は変わると背後の電源関連設定や PPM(Processor Power Management)の挙動にも影響します。つまり、ここが違うだけでコア駐車や性能スケーリングの方針が変わり得ます。
一方、Power plan は Balanced、High performance などの伝統的な電源プランです。
powercfg /list や powercfg /getactivescheme で確認できます。
ここでややこしいのは、Windows には power mode のオーバーレイとpower planの両方があることです。 関係を図にすると、こうなります。
flowchart TB
subgraph upper["上の層: Power mode - オーバーレイ"]
direction LR
M1["Best power efficiency"]
M2["Balanced"]
M3["Best performance"]
end
subgraph lower["下の層: Power plan - 電源プラン"]
direction LR
P1["Balanced"]
P2["High performance"]
P3["custom plan"]
end
UI["設定アプリ<br/>Power and battery の Power mode"] --> upper
CLI["powercfg /setactive で切り替え"] --> lower
upper --> PPM["実際に効く電源設定<br/>PPM とグラフィックスのサブグループ"]
lower --> PPM
AC["AC 給電かバッテリーか"] --> PPM
PPM --> RESULT["周波数の上限 / コア駐車 / 性能スケーリング"]
上の層だけ、下の層だけを見ても実際の挙動は決まりません。だからベンチ結果には、最低でも次を記録してください。
- AC かバッテリーか
- Power mode が何か
- Active power plan が何か
この 3 つを書いていないベンチ結果は、後から見返したときに条件を復元できません。
まず固定すべき電源条件
-
ノート PC は必ず AC 接続で比較する バッテリー運用は、意図しない制限が入りやすいです。
-
Power mode を固定する ベンチ用途なら、まず
Best performanceを試します。 -
Active power plan を記録する
powercfgで現在値を残します。
powercfg /list
powercfg /getactivescheme
powercfg /list の出力は、Microsoft のドキュメントでは次の形で示されています。アクティブなプランの行末に * が付きます。日本語環境では、見出しとプラン名が日本語で出ます。
Existing Power Schemes (* Active)
-----------------------------------
Power Scheme GUID: {guidPlan1} (Balanced) *
Power Scheme GUID: {guidPlan2} (Power saver)
ここで出た GUID を、そのまま結果ファイルの power_plan 欄へ書き写します。名前ではなく GUID を残すのがポイントです。同じ「バランス」でも、複製やカスタマイズをした別プランのことがあるからです。
- 必要なら High performance に切り替える
# Balanced
powercfg /setactive 381b4222-f694-41f0-9685-ff5bb260df2e
# High performance
powercfg /setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c
Power mode はコマンドで切り替えられるのか
ここは詰まりやすいところです。powercfg の公開されているコマンドライン オプション一覧に、Power mode(オーバーレイ)そのものを選び直すオプションはありません。切り替えは設定アプリの Settings > System > Power & battery から行うのが正規の手順です。
一方で、powercfg はオーバーレイ スキームの 設定値の読み書き には対応しています。ドキュメントには次の記述があります。
powercfg /qにオーバーレイのエイリアスとサブグループを渡すと、オーバーレイ側の設定を読めるpowercfg /setacvalueindexと/setdcvalueindexはオーバーレイ スキームにも使える- スキームを指定しなかった場合は、現在アクティブなオーバーレイ(オーバーレイが無ければ現在の電源プラン)が対象になる
- エイリアスの一覧は
powercfg /aliasesで確認できる
つまりコマンドでできるのは「いま効いているオーバーレイの中身を読む・調整する」ことで、「どのオーバーレイを選ぶか」を変えることではありません。ベンチの再現手順としては、設定アプリで Power mode を人手で固定し、その値を結果に書き残すのが現実的です。手順書には「Power mode = Best performance に設定した」と明記し、実行のたびに画面で確認します。
「High performance が出ない」は普通にある
ここもハマりどころです。 Microsoft のドキュメントでは、Modern Standby 対応デバイスでは Balanced、または Balanced から派生したプランしか許可されないとされています。 なので、「High performance が見当たらない、壊れた?」ではなく、その機種の設計上そうなっている可能性があります。
また、Microsoft は「Power mode が変更できない場合、custom power plan が選ばれているかもしれないので、まず Balanced を選んでみる」と案内しています。Power mode の UI が動かないときは、ここを疑うのが早いです。
バックグラウンドノイズを潰す
Windows は、こちらが静かに測りたいときでも、裏で更新やインデックス作成やスキャンを動かします。まずはその量を減らします。
まずは再起動して、落ち着くまで待つ
設定変更後は一度再起動し、ログイン後すぐには走らせず、数分待ちます。 起動直後は、更新、インデックス、同期、Defender、各種常駐がまだ暴れています。
厳密な比較なら clean boot を使う
Microsoft は、clean boot によって最小限のスタートアップ構成にできる手順を案内しています。
msconfig で Microsoft 以外のサービスを止め、Task Manager で Startup apps を無効化する方法です。
これはノイズを減らすには強力です。 ただし、日常利用環境とは離れるので、「コード差を見るためのラボ比較」で使うのが向いています。
通知を黙らせる
Windows の通知バナーは、軽く見えて意外と邪魔です。 視覚的に邪魔なだけでなく、実行タイミングやフォーカス、裏のアプリ活動を変えることがあります。
Do not disturb を手動で有効にするか、少なくともベンチ中は通知を切ります。
検索インデックスと同期を抑える
ベンチ対象が大量ファイルを読む、生成物を大量に書く、ソースツリーを何度も作り直す、というタイプなら、検索インデックスやクラウド同期が地味に刺さります。
- ベンチ用のディレクトリを検索対象から外す
- OneDrive / Dropbox / Google Drive などの同期を止める
- ブラウザ、Teams、Discord、Slack を閉じる
このへんは派手さはないですが、効くときはかなり効きます。
熱を揃えない比較は、だいたい熱を比べている
CPU や GPU は、冷えているときと温まった後で動作クロックが変わります。同じコードでも、実行のたびに条件が変わるということです。 特にノート PC、薄型ミニ PC、小型デスクトップは顕著です。
守るべきルール
- 室温をできるだけ揃える
- ノート PC の置き方を固定する
- AC アダプタ、ドック、外部ディスプレイ構成を固定する
- ベンチの前に重い作業をしない
- 初回実行と定常状態を分けて測る
実行順序は交互にする
A を 10 回やってから B を 10 回、は避けます。 熱、キャッシュ、バックグラウンド活動の偏りが載るからです。
おすすめは次のどれかです。
A B A B A B ...A B B A A B B A ...- ランダム順序を事前生成して、その順に回す
何を測るかで「速い」の意味は変わる
「速い」を 1 個の数に押し込むと、だいたい事故ります。 Windows で見るべき代表的な指標は次の 3 つです。
1. Wall-clock time(実時間)
ユーザーが待つ時間です。 エンドツーエンドの体感に一番近いので、まず最初に見る値はこれです。
Windows では QueryPerformanceCounter (QPC) が高分解能の時刻取得に使えます。
managed code なら Stopwatch 系を使うのが基本です。
DateTime.Now でミリ秒を眺めるのは、さすがにちょっと無防備です。
2. CPU time(ユーザー + カーネル時間)
GetProcessTimes で取得できる、プロセスが実際に CPU を使った時間です。
これは計算効率を見るのに便利です。 たとえば wall-clock では速くなったのに CPU time が変わらないなら、キャッシュ、I/O、待ち時間、スケジューリングが効いている可能性があります。
3. Cycle count(CPU サイクル数)
QueryProcessCycleTime で、プロセス全体の CPU サイクル数を取れます。
これも CPU work を見る指標ですが、wall-clock とは別の面を見せてくれます。 特に「待ち時間は同じだが、計算部分は軽くなっているのか」を見たいときに便利です。
priority、affinity、NUMA は最後の手段
このあたりは効くことがあります。 でも、効くからといって最初から触ると、別の現象を作りやすいです。
まずは普通に測る
デフォルト状態で差が出るなら、その差自体に価値があります。
いきなり /high や /affinity を入れると、「実際の Windows では起きない条件」を持ち込むことになります。
使うなら、目的を明確にする
- /high: 他のプロセスの邪魔を受けにくくしたい
- /affinity: CPU 配置を固定して比較したい
- NUMA 制御: 大規模マシンでメモリ局所性まで揃えたい
Windows の start コマンドは、priority class や affinity mask を付けて起動できます。
start "" /high /wait myapp.exe --bench case1.json
start "" /affinity F /high /wait myapp.exe --bench case1.json
ただし /realtime はやめる
/realtime は使えますが、使わないほうがいいです。
ノイズ除去ではなく、別の事故を作る方向に働きがちです。
測定手順のおすすめ
ここまでを踏まえた、実運用しやすい手順をまとめます。
ラボ寄りの比較手順
- 比較対象を固定する
- commit hash / build number
- compiler / runtime version
- Debug / Release
- ログ、assert、トレース有無
- マシン条件を固定する
- Windows build
- BIOS / UEFI version
- driver version
- AC 接続
- 室温、設置方法
- 電源条件を固定する
- Power mode を決める
- Active power plan を記録する
- 再起動する
- ベンチ前に数分待つ
- 必要なら clean boot
- warm-up を入れる
- A / B を交互に回す
- 回数を確保する
- 中央値・最小・最大・p95 を残す
- raw data を保存する
- 差が小さければ ETW / WPR を取る
何回まわすか
9 番の「回数を確保する」の目安も決めておきます。以下は統計的な厳密解ではなく、実務での落としどころです。
| 見たいもの | 1 バージョンあたりの実行回数の目安 |
|---|---|
| 中央値だけ見て、大きめの差(1 割以上)を確認したい | 10 回 |
| 数 % の差を主張したい。ばらつきも見たい | 30 回 |
| p95 まで読みたい | 30 回以上。20 回では p95 が上位 1〜2 個の値そのものになり、外れ値の影響を直接受けます |
所要時間は 1 回の実行時間 × 回数 × バージョン数 + warm-up で見積もれます。1 回 30 秒の処理を A / B それぞれ 30 回なら、warm-up を入れて 35 分前後という計算です。これが現実的でないときは、回数を削るより 測る対象を小さく切る(重い工程だけを切り出す)ほうが筋がよいです。
止めどころに迷うなら、回数を増やしながら中央値の推移を見て、増やしても動かなくなったところで止めるのが分かりやすいやり方です。
記録しておくと後で助かる項目
ベンチの CSV や JSON には、少なくとも次を残しておくと強いです。
timestamp,version,scenario,elapsed_ms,user_ms,kernel_ms,cycles,power_mode,power_plan,ac_or_dc,room_temp_c,notes
可能なら、さらに次もあると便利です。
cpu_package_temp_start_c,cpu_package_temp_end_c,affinity_mask,priority_class,windows_build,driver_version
ベンチは、測ることより後で解釈できることのほうが大事だったりします。
平均だけでなく、中央値と分布を見る
平均は便利ですが、Windows ベンチでは簡単に壊れます。 1 回だけ Defender が入った、通知が出た、別プロセスが SSD を叩いた、というだけで平均が持っていかれます。
おすすめはこの組み合わせです。
- 中央値: まずこれを見る
- p95 / p99: tail が悪化していないかを見る
- min / max: 外れ方を見る
- 箱ひげ図や散布図: 差が小さいときに役立つ
差が出たときの読み方
結果の解釈は、組み合わせで見ると分かりやすいです。
wall-clock だけ速い
I/O、待ち時間、キャッシュ、スケジューリングの改善かもしれません。
CPU time も cycle も下がっている
実装そのものが軽くなっている可能性が高いです。
1 回目だけ遅い / 速い
cold / warm の差です。起動・初期化・キャッシュ生成・JIT を疑います。
回を重ねるほど遅くなる
熱、スロットリング、メモリ圧迫、バックグラウンド活動を疑います。
ETW / WPR で「なぜ速いか」まで掘る
差が小さい、あるいは理由が読めないときは、Windows の ETW(Event Tracing for Windows)系ツールに進むのが王道です。
Microsoft の Windows Performance Recorder (WPR) は ETW ベースの記録ツールで、Windows ADK に含まれています。
CPU、I/O、context switch、ページフォールトなどをまとめて取れます。
最低限ならこんな感じです。
wpr -start CPU -filemode
REM ここでベンチを実行する
wpr -stop trace.etl
WPA で開いたあと、まず見るグラフはだいたい決まっています。
| 見たいこと | 開くグラフ | 読み方 |
|---|---|---|
| どの関数で CPU を使っているか | CPU Usage (Sampled) | Weight で並べ替え、A と B でスタックを比べる。サンプリングなので、DPC / ISR のような短い処理は写りにくい |
| なぜ待っているのか | CPU Usage (Precise) | Ready 時間、待ち時間、コンテキストスイッチの理由を見る。lock 待ちや I/O 待ちの差はここに出る |
| ドライバー起因で詰まっていないか | DPC/ISR | モジュール別の時間を見る。ここが大きいなら、そもそもアプリ側の差ではない |
| ディスクが効いているか | Disk Usage | I/O の回数とサイズ、サービス時間を見る |
比較のときは、同じシナリオで A と B のトレースを 1 本ずつ取り、同じグラフを並べて見るのが基本です。1 本だけ見ても「これは遅いのか」を判断できません。
この段階まで来ると、 「B のほうが 3% 速い」ではなく、 「B は lock 待ちが減って ready time が下がっている」 「A は file open が増えて cold start が遅い」 のように、理由付きで話せるようになります。
1 枚でまとめたチェックリスト
最後に、そのまま手順書へ貼れる形にしておきます。
固定する
- 比較対象を固定した(commit hash / build number / Debug か Release / PGO などのビルド条件 / ログや assert の有無)
- ノート PC は AC 接続にした
- Power mode を設定アプリで固定した
- Active power plan を
powercfg /getactiveschemeで確認した - 通知を止めた。検索インデックスとクラウド同期を止めた
- 必要なら clean boot にした
- 再起動し、数分待ってから始めた
実行する
- warm-up を入れた
- cold(初回)と warm(定常)を分けて測った
- A / B を交互、またはランダム順で回した
- 回数を決めて回した(目安は上の表)
記録する
- 1 実行 1 行の raw data を残した(
elapsed_ms/user_ms/kernel_ms/cycles) - AC か DC か、Power mode、power plan の GUID、Windows build、driver version を残した
- 室温と設置状態を残した
- 固定しなかった条件も書き残した
解釈する
- 中央値を見た。平均だけで判断していない
- p95 / p99 で tail を見た
- min / max で外れ値を確認した
- wall-clock / CPU time / cycle の組み合わせで理由を推測した
- 差が小さいときは ETW / WPR まで掘った
まとめ
Windows でバージョン違いのプログラムを比較するときに、本当に効くのは派手な裏技ではありません。 大事なのは、次のような地味だけど再現性に効く作法です。
- AC / Power mode / power plan を固定して記録する
- cold と warm を分ける
- A / B を交互に回す
- 中央値と分布を見る
- 必要なら clean boot
- 差が小さければ ETW / WPR で理由まで掘る
そして一番大事なのは、何を固定して、何を固定しなかったかを結果と一緒に書くことです。 ベンチは速さの比較であると同時に、実験条件の記録でもあります。
条件の書かれていない高速化報告は、同じ結果を出せるかどうかを他人が確かめられません。数字だけが残り、再現の手立てが残らないからです。 逆に条件がきちんと書かれていれば、たとえ差が小さくても、その結果にはちゃんと価値があります。
参考資料
- Microsoft Support: Change the power mode for your Windows PC
- Microsoft Learn: Power Policy Settings
- Microsoft Learn: Customize the Windows performance power slider
- Microsoft Learn: Powercfg command-line options
- Microsoft Support: How to perform a clean boot in Windows
- Microsoft Support: Notifications and Do Not Disturb in Windows
- Microsoft Support: Search indexing in Windows
- Microsoft Learn: Configure custom exclusions for Microsoft Defender Antivirus
- Microsoft Support: Device Security in the Windows Security App
- Microsoft Learn: QueryPerformanceCounter function
- Microsoft Learn: Acquiring high-resolution time stamps
- Microsoft Learn: GetProcessTimes function
- Microsoft Learn: QueryProcessCycleTime function
- Microsoft Learn: start command
- Microsoft Learn: SetPriorityClass function
- Microsoft Learn: SetProcessAffinityMask function
- Microsoft Learn: Processor Groups
- Microsoft Learn: Windows Performance Recorder
- Microsoft Learn: WPR Command-Line Options
- Microsoft Learn: CPU Analysis in Windows Performance Analyzer - どのグラフで何を見るか。
- Microsoft Learn: Set the Default Power Plan -
powercfg -LISTの出力例。
関連する記事
同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。
C#/C++/Java/Goの実行速度を公平に比較する方法
C#、C++、Java、Go の実行速度を公平に比較する方法を、測定設計、warm-up、環境固定、統計の見方、具体的なベンチ項目まで整理します。
マルチスレッドの実務ベストプラクティス C言語編 ── Win32 APIの流儀で安全に書く
C言語×Win32のマルチスレッドは、_beginthreadexでのスレッド作成、SRWロックと条件変数、Interlocked、停止イベント+WaitForMultipleObjectsの停止設計が定石。TerminateThreadの危険とDllMainの制約まで整理...
マルチスレッドの実務ベストプラクティス C++編 ── RAIIとjthreadで事故を構造から消す
C++のマルチスレッドはデータ競合が未定義動作になる世界。std::threadのデストラクタの罠、jthreadとstop_tokenによる停止設計、scoped_lockのデッドロック回避、atomicの正しい位置づけ、Win32同期APIとの使い分けまで整理します。
マルチスレッドの実務ベストプラクティス .NET編 ── スレッドを増やす前に決めておくこと
「スレッドを立てたら、たまに落ちる・固まる」を防ぐ設計の定石を.NET/C#向けに整理。スレッドを自分で作らずTaskに乗る、共有可変状態を減らす、ロックの規律、CancellationTokenでの停止設計、UIスレッドの扱いまで解説します。
ボリュームシャドウコピー(VSS)の仕組みと実務 ── 使用中ファイルのバックアップがなぜ取れるのか
使用中のファイルは共有違反でコピーできないのに、バックアップソフトはなぜ取れるのか。ボリュームシャドウコピー(VSS)のリクエスター・ライター・プロバイダーの役割分担、コピーオンライトの仕組み、vssadminの実務と差分領域の落とし穴を解説します。
関連トピック
このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。
Windows技術トピック
Windows 開発、不具合調査、既存資産活用の技術トピックをまとめた入口です。
このテーマがつながるサービス
この記事は次のサービスページにつながります。近い入口からご覧ください。
技術相談・設計レビュー
性能比較の設計、計測条件の揃え方、ETW / WPR での掘り下げまで含めて、技術相談・設計レビューと相性がよいテーマです。
不具合調査・原因解析
バージョン間で速い・遅いの差が出たときに、電源条件、熱、バックグラウンドノイズ、実装差のどこが原因か切り分ける流れは、不具合調査・原因解析として進めやすいです。
よくある質問
この記事のテーマについて、相談時によくある質問をまとめています。
- Windowsでベンチマーク結果がぶれる主な原因は何ですか?
- 電源モードやpower plan、熱、バックグラウンド更新、検索インデックス、ウイルススキャン、優先度・アフィニティ、実行順序、キャッシュ状態など多層の要因があります。同じWindowsマシンでも、これらの条件が揃っていなければ実質的に別の実験になります。特にノートPCではAC接続かバッテリー駆動かで挙動が大きく変わるため、必ずAC接続で比較し、条件を記録することが重要です。
- power modeとpower planは何が違いますか?
- Power modeは設定アプリのPower & batteryで選ぶBest power efficiency・Balanced・Best performanceの切り替えで、背後の電源関連設定やPPM(Processor Power Management)の挙動に影響します。Power planはpowercfgで確認できるBalancedやHigh performanceなどの伝統的な電源プランです。Windowsには両方が存在するため、ベンチ結果にはACかバッテリーか・Power mode・Active power planの3つを最低限記録しておく必要があります。
- High performanceの電源プランが表示されないのは故障ですか?
- 故障ではない可能性が高いです。Microsoftのドキュメントでは、Modern Standby対応デバイスではBalanced、またはBalancedから派生したプランしか許可されないとされています。つまりその機種の設計上High performanceが出ないことは普通にあります。またPower modeのUIが変更できない場合は、custom power planが選ばれている可能性があるため、まずBalancedを選んでみるのが早いです。
- バージョンAとBの速度比較はどんな順序で実行すべきですか?
- Aを先に全部回してからBを回すのは避けるべきです。熱・キャッシュ・バックグラウンド活動の偏りが片方だけに載るからです。A B A B と交互に回すか、事前に生成したランダム順序で実行します。また冷えた1回目と温まった後の定常状態を分けて測り、平均だけでなく中央値・p95・最小・最大を見ることで、外れ値に結果を持っていかれるのを防げます。