在 Windows 上如何比較不同版本程式的執行速度 - 從電源模式等環境的對齊到可到的極限
· 小村 豪 · Windows, Benchmark, Performance, Profiling, Power Management
想在 Windows 上比較程式版本 A 與 B。 這時最不該做的事,就是在同一台機器上各跑 1 次,然後說「看起來 B 快 8%」。
這 8% 可能真的是程式差異。 但實際上,更可能是 電源模式、power plan、熱、背景更新、搜尋索引、防毒掃描、親和性、執行順序、快取狀態 其中之一——這是 Windows benchmark 的日常,相當泥濘的世界。
本文整理在 Windows 上比較不同版本程式執行速度時,如何 儘量貼近「程式差異」 的做法。
以 Windows 11 為主,但 powercfg 與 start 這類指令大部分在 Windows 10 也通用。
先下結論
先把結論列出來,提高重現性的要訣有 6 項:
-
先決定「要比較什麼」
想看程式本身差異,還是真實使用者體感,該對齊的環境不同。 -
把 power mode 與 power plan 當成兩件事記錄
在 Windows 上馬虎處理這裡,比較很容易變成在比 OS 的省電策略。 -
冷啟動第 1 次與熱機後的穩態要分開
第 1 次就特別快、後半特別慢,都不罕見。 -
A→B→A→B 這樣交替跑
先把 A 全跑完再跑 B,會把熱與背景活動的偏差全背下。 -
平均之外還要看中位數與分佈
一個離群值就能毀掉世界觀,平均比想像中還脆。 -
差距小的時候,就用 ETW / WPR 挖到理由
靠體感辯論,大多是霧中互毆。
先決定你要比較什麼
「速度比較」其實分成兩種。
1. 想看程式差異的比較
因為演算法、資料結構、編譯器優化、runtime 更新等因素,想知道 實作本身是否變快。
這種情況要把環境雜訊削到最低: 專屬 benchmark session、固定 power mode、停通知、壓制搜尋索引與雲端同步,必要時做 clean boot。
2. 想看真實使用者體感的比較
想知道發布後,使用者在日常 Windows 上感受到的速度。
這種情況 不能把現實的雜訊全部消掉。 要在包含 OneDrive、Defender、通知、一般電源設定等的「像日常的環境」做比較,才會貼近現實結果。
把這兩種混用,結論就會擰著走: 「實驗室裡快 12%、現實中誤差」「現實中快、但 CPU 時間沒變」——都很常見。
Windows 上讓結果晃動的主要因素
先粗略列出會讓結果亂跳的因素:
| 層 | 晃動因素 | 典型例子 |
|---|---|---|
| 硬體 | CPU / GPU、記憶體、SSD、散熱 | 薄筆電、有沒有散熱底座 |
| 韌體 | BIOS / UEFI、OEM 控制 | 省電策略、風扇控制 |
| OS | Windows build、驅動、更新狀態 | 同台 PC 更新後行為就變了 |
| 電源 | AC / DC、power mode、power plan | 改電池供電就像另一個世界 |
| 熱 | 室溫、風扇、先前負載 | 第 1 次 turbo、後半失速 |
| 背景 | Update、Defender、同步、通知 | 執行中被掃描或同步打到 |
| 排程 | 優先權、親和性、NUMA | 機器不同,CPU 配置就不同 |
| 資料/快取 | OS 快取、應用快取 | 第一次慢、之後才快 |
| 建置條件 | Debug / Release、PGO、有無 log | 本來就在比不同東西 |
簡單說,「同一台 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)行為也會跟著變。也就是光這裡不同,核心停駐(core parking)與效能 scaling 策略就可能不同。
另一方面,Power plan 則是 Balanced、High performance 等傳統電源方案。
可以用 powercfg /list 或 powercfg /getactivescheme 確認。
麻煩的是,Windows 同時存在 Power mode 的 overlay 與 Power plan。 所以 benchmark 結果至少要記錄:
- AC 或電池
- Power mode 是什麼
- Active power plan 是什麼
沒寫這 3 項的 benchmark 結果,日後回看會很痛苦。
先要固定的電源條件
-
筆電務必接 AC 比較
電池運作常被加上意料外的限制。 -
固定 Power mode
benchmark 用途可以先試Best performance。 -
記錄 Active power plan
用powercfg把當時的值留下。
powercfg /list
powercfg /getactivescheme
- 必要時切成 High performance
# Balanced
powercfg /setactive 381b4222-f694-41f0-9685-ff5bb260df2e
# High performance
powercfg /setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c
「High performance 找不到」並不罕見
這裡也是地雷。 Microsoft 文件說明:在支援 Modern Standby 的裝置上,只允許使用 Balanced 或 Balanced 衍生的方案。 所以看到「High performance 沒有了,壞掉了嗎?」,更可能是 這台機器的設計本來就這樣。
Microsoft 也指出:若 Power mode 無法變更,可能是用了 custom power plan,建議先切回 Balanced。Power mode UI 動不了時,這是首先該懷疑的方向。
抑制背景雜訊
Windows 是勤勞的 OS,你靜靜想 benchmark 時,它還在背後忙很多事。
先重開機,靜置一下
變更設定後先重開機,登入後不要馬上跑,等幾分鐘。 剛啟動時更新、索引、同步、Defender、各種常駐程式都還在躁動。
認真比較時用 clean boot
Microsoft 有說明怎麼做 clean boot,讓啟動項最精簡:
用 msconfig 停用非 Microsoft 的服務,再用 Task Manager 停用 Startup apps。
這招 降噪 很有效。 但它遠離日常環境,適合用在「專門比較程式本身差異的 lab 比較」。
讓通知閉嘴
Windows 的通知看似不起眼,其實很會打擾人。 不只視覺干擾,還會改變執行時機、焦點、背景應用活動。
手動開 Do not disturb,或至少在 benchmark 期間把通知關掉。
抑制搜尋索引與雲端同步
若 benchmark 會大量讀檔、寫檔、反覆重建原始樹,搜尋索引與雲端同步會低調地插你一刀。
- 把 benchmark 用的資料夾排除在搜尋索引外
- 停掉 OneDrive / Dropbox / Google Drive 的同步
- 關掉瀏覽器、Teams、Discord、Slack
不起眼,但需要時效果很實在。
不對齊熱,等於在比熱
CPU 或 GPU 冷的時候和熱的時候是兩種生物。 薄筆電、薄型 mini PC、小型桌機更明顯。
要守的規則
- 儘量對齊室溫
- 筆電的擺放方式要固定
- AC 變壓器、Dock、外接螢幕組合要固定
- benchmark 前不要做重工作
- 第一次執行與穩態要分開量
執行順序要交替
不要 A 跑 10 次、B 跑 10 次。 熱、快取、背景活動的偏差都會押到某一邊。
建議順序:
A B A B A B ...A B B A A B B A ...- 事先生成隨機順序,按順序跑
量什麼,「快」就變成不同意思
把「快」壓到一個數字,多半會出事。 Windows 常用的有 3 個指標。
1. Wall-clock time(實際時間)
使用者在等的時間。 最貼近端對端體感,所以先看這個。
Windows 上 QueryPerformanceCounter(QPC)可以拿到高解析度時間。
managed code 則用 Stopwatch 系。
用 DateTime.Now 看毫秒,有點太無防備。
2. CPU time(user + kernel)
GetProcessTimes 可以拿到行程實際用到的 CPU 時間。
用來 看計算效率 相當好。 例如 wall-clock 變快但 CPU time 沒變,可能是快取、I/O、等待、排程在起作用。
3. Cycle count(CPU cycle 數)
QueryProcessCycleTime 能拿到整個行程的 CPU cycle 數。
同樣是量計算量,但和 wall-clock 是另一個面向。 想看「等待沒變,但計算部分變輕了嗎」時很有用。
priority、affinity、NUMA 放最後
這些有效。 但一開始就動,常會製造另一種現象。
先用預設狀態量
預設狀態就有差,那個差本身就有價值。
一上來就 /high、/affinity,等於帶入 「真實 Windows 不會出現的條件」。
真的要用,就要講清楚目的
- /high:不想被其他行程干擾
- /affinity:把 CPU 配置固定來比較
- NUMA 控制:在大型機器上連記憶體 locality 一起對齊
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 雖然能用,最好不要。
它常常不是在降噪,而是在製造另一種事故。
建議的量測流程
把上面這些整理成好操作的流程。
偏 lab 的比較流程
- 固定比較對象
- commit hash / build number
- compiler / runtime 版本
- Debug / Release
- log、assert、trace 有無
- 固定機器條件
- Windows build
- BIOS / UEFI 版本
- 驅動版本
- 接 AC
- 室溫、擺放方式
- 固定電源條件
- 決定 Power mode
- 記錄 Active power plan
- 重新開機
- benchmark 前等幾分鐘
- 必要時做 clean boot
- 加上 warm-up
- A / B 交替跑
- 確保回合數
- 留下中位數、最小、最大、p95
- 保存 raw data
- 若差距很小,再取 ETW / WPR
留下來之後會救你一命的欄位
benchmark 的 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
benchmark 真正重要的,有時不是 量 本身,而是 後面能不能解釋。
除了平均,也要看中位數與分佈
平均方便,但在 Windows benchmark 上很容易被摧毀。 Defender 偶爾插一下、通知彈一下、別的程式打一下 SSD,平均就被帶走。
建議:
- 中位數:先看
- p95 / p99:看 tail 有沒有惡化
- min / max:看離群程度
- 箱型圖或散佈圖:差距小時特別有用
出現差異時怎麼讀
把結果組合起來看比較清楚。
只有 wall-clock 變快
可能是 I/O、等待、快取、排程改善。
CPU time 與 cycle 都下降
很可能是實作本身變輕。
只有第 1 次慢 / 快
cold / warm 的差異。懷疑啟動、初始化、快取建立、JIT。
回合越多越慢
懷疑熱、throttling、記憶體壓力、背景活動。
用 ETW / WPR 挖「為何變快」
當差距小、或理由不清楚時,走 Windows 的 ETW(Event Tracing for Windows)路線是王道。
Microsoft 的 Windows Performance Recorder(WPR)是以 ETW 為基礎的錄製工具,包含在 Windows ADK 裡。
CPU、I/O、context switch、page fault 都能一起抓。
最小用法:
wpr -start CPU -filemode
REM 在這裡執行 benchmark
wpr -stop trace.etl
走到這一層,就不再是: 「B 快 3%」, 而能說出: 「B 的 lock 等待變少,ready time 下降」 「A 的 file open 變多,cold start 變慢」 這種帶理由的結論。
總結
在 Windows 上比較版本差異,真正有效的不是花俏的偏門招。 真正有用的,是下列 樸素但提升重現性 的做法:
- 固定並記錄 AC / Power mode / Power plan
- 分開 cold 與 warm
- A / B 交替跑
- 看中位數與分佈
- 必要時做 clean boot
- 差距小時用 ETW / WPR 挖原因
最重要的是:把「固定了什麼、沒固定什麼」和結果寫在一起。 benchmark 同時也是實驗條件的紀錄。
沒有條件的「速度報告」,像偶爾猜中的占卜,但重現性相當可疑。 反過來,只要條件寫得扎實,就算差距很小,結果也真的有價值。
參考資料
- 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
相關文章
共用相同標籤的最新文章。能以相近的主題延伸理解。
各種程式語言的速度測量與比較應該怎麼做 - C# / C++ / Java / Go 以相同條件比較的實踐指南
整理在公平的條件下比較 C#、C++、Java、Go 速度的具體做法,包含區分啟動時間與穩態的 throughput、區分 cold 與 warm、固定建置條件與環境、以共通輸入確認正確性、看中位數與分布等流程,理解到不應以一個 bench 決定語言優劣的視角。
整理 Windows 的字元編碼與換行符 - Shift_JIS / UTF-8 / UTF-16、亂碼、CRLF / LF,為何混亂
本文整理 Windows 上字元編碼與換行符容易混亂的核心:bytes、UTF-8 與 CP932、UTF-16LE、BOM、CRLF 與 LF 是不同軸的概念,亂碼源於以錯誤前提 decode,且誤儲存後無法還原。讀完即可在規格中寫出明確的 encoding 與換行約定,...
ClickOnce 是什麼 - 以實務視角整理機制、更新、適合場面・不適合場面
本文以實務視角整理 ClickOnce 是什麼,從 manifest、快取、更新、簽章的構造,到適合公司內部 .NET 桌面業務應用程式的案件與不適合 machine-wide 或 service、driver 等深度 OS 整合的案件,幫助讀者判斷是否採用並掌握 depl...
用 Windows 沙箱加速 Windows 應用程式開發的驗證 - 以實務向整理管理員權限問題、乾淨環境、權限不足・資源不足的重現
整理在 Windows 應用程式開發中如何運用 Windows Sandbox 加速驗證的實務做法。透過按情境分檔的 .wsb、唯讀輸入與專用 Outbox 寫入分離、在容器內另建標準使用者重現權限不足、以及降低記憶體和關閉 vGPU 製造資源不足偏向,把每次的乾淨環境準備...
Windows 的 DLL 名稱解析機制 - 以實務角度整理搜尋順序、Known DLLs、API set、SxS
從實務角度整理 Windows 的 DLL 名稱解析,說明 loader 在掃描檔案系統前會先處理 DLL redirection、API set、SxS、Known DLLs,並用 SetDefaultDllDirectories 與 LoadLibraryEx 旗標縮小...
相關主題
與本文相近的主題頁面。以本文為起點,可進一步連到相關服務與其他文章。
Windows 技術主題
彙整 KomuraSoft LLC 關於 Windows 開發、故障調查與既有資產活用文章的主題中心。
作者檔案
本文作者的個人檔案頁面。
Go Komura
小村軟體有限公司 代表
以 Windows 軟體開發、技術諮詢與故障調查為中心,在難以重現的故障調查與既有資產仍在運作的專案上具有優勢。