# 性能評価計測結果 (Performance Evaluation Results)

3 バージョン（v1.6 / v1.7 / 現行）の実機 MEMMONITOR 計測結果をまとめる．計測の目的・手段・移植方針・指標定義は [PLAN_04_性能評価計測計画](../03_PLAN/PLAN_04_性能評価計測計画.md) を参照する．

## 計測条件 (Conditions)

- 計測手段: 実機 MEMMONITOR（メモリ観測ウィンドウ＋プレビュー計測）．
- カメラ: IScam（ImagingSource DFK 23UX249）．
- ビルド: `Debug|x64`，`MEMMONITOR` 有効・`WHITEBOARD` 無効．
- 副モニタ（セカンダリディスプレイ）: **ON**（F9 トグルは使わず ON のまま）．
- サンプリング: 500ms 間隔．メモリ主指標は `private_MB`（`Process.PrivateMemorySize64`）．
- 観測窓の実行スレッド: 旧版（`bench/*`）はプレビューが毎フレーム `Invalidate()` で本体 UI スレッドを埋めるため，観測窓を**専用 UI スレッド**で開く（本体・プレビューの挙動は不変の観測側の措置．同一スレッドだとグラフ描画とサンプリングが WM_PAINT 洪水に飢餓し，サンプル間隔が乱れるため）．現行はタイマー駆動で飢餓しないため同一スレッドのまま計測した．

## 基準プロトコル (Reference Protocol)

現行で実測した 1 本の記録を基準とし，**撮影・校正の秒数を全版で揃える**．撮影は**単発撮影（1 枚撮影）の繰り返し**．

| 時刻 | 動作 |
| --- | --- |
| 0〜32 秒 | プレビュー放置（副モニタ ON） |
| 32.5〜36.1 秒 | 校正 1 回（処理時間 約 3.5 秒．アプリ側処理で固定） |
| 62 / 92 / 123 秒 | 単発撮影（約 30 秒間隔で 3 回） |
| 123〜303 秒 | プレビュー放置（約 180 秒．プレビュー経路リークの観測区間） |
| 303 秒 | 単発撮影 1 回 |
| 約 348 秒 | 停止・CSV 保存 |

旧版（v1.6 / v1.7）もこの秒数・順序・撮影間隔に合わせて再現し，同じ時間軸で 3 版を重ねて比較する．

## 現行バージョンの結果 (Current Version)

データ: [data/perf_current.csv](data/perf_current.csv)（689 サンプル・約 348 秒）．

### メモリ（保存経路 S1・プレビュー経路 S2）

| 指標 | 値 |
| --- | --- |
| `private_MB` アイドル時ベースライン | 約 150 MB |
| `private_MB` 校正後の定常包絡線 | 約 180〜200 MB（約 348 秒を通じて**水平**） |
| 撮影時の一時ピーク | 452〜509 MB（**1〜2 秒で ~180 MB に完全復帰**） |
| 終端（348 秒）の `private_MB` | 約 182 MB（校正後ベースラインと同一） |
| `gdi_objects` / `handle_count` | 68〜95 / 780〜855（**単調増加なし**） |

- **リークなし＝天井一定**．撮影のたびに 452〜509 MB へ跳ねるが確定的に解放され，包絡線は水平．180 秒のプレビュー放置区間でも上昇しない（プレビュー経路リーク修正の裏付け）．
- グラフはのこぎり波になるが，見るべきはピーク包絡線のトレンド（[PLAN_04 の「結果の読み方」](../03_PLAN/PLAN_04_性能評価計測計画.md)参照）．

### プレビュー性能（S3）

| 指標 | 値 |
| --- | --- |
| `main_copy_ms`（FastClone コピー時間） | 大半 2.3〜2.8 ms（平均 約 2.6 ms．周期的に 5〜6 ms のスパイク） |
| `callback_fps`（ShowImage 実効レート） | 約 30（カメラレート律速） |
| 本モニタ実描画 FPS | 約 19 で一定 |
| 副モニタ実描画 FPS | **約 19 で一定（飢餓なし）** |

- FastClone により毎フレームのコピーが約 2.6 ms．
- 校正完了後も副モニタが約 19fps を維持＝両プレビューのタイマー駆動化により副モニタ描画飢餓が起きない（旧版の校正後 ≈2fps 飢餓と対比になる想定）．

### 注記（誤読を避けるため）

- 撮影サンプル行（例 61.7 秒）で `callback_fps` ≈2.5・FPS ≈1 に落ちるのは，撮影が UI を約 1.5 秒同期ブロックし 500ms サンプラが 1 コマ捉えたもの．**1 サンプルだけの谷で即回復**＝正常挙動．
- 30〜32 秒（校正直前）の一時的な FPS 低下はチャート検出の立ち上がりによる一過性のもの．

## v1.7 の結果 (v1.7)

データ: [data/perf_v1.7.csv](data/perf_v1.7.csv)（436 サンプル・約 315 秒）．`bench/v1.7`（v1.7 に `bench/v1.6` の移植を cherry-pick．v1.7 の保存経路メモリ効率化と観測フックが両立）で基準プロトコルを再現．計測マッピングは v1.6 と同じ（`main_copy_ms ≈ 0`，全画面コピーは `sub_copy_ms`）．

v1.7 は **v1.6 ＋ 保存経路のメモリ効率化のみ**でプレビュー経路は v1.6 と同一構造．結果もそれを裏付ける．

| 指標 | v1.7 | （参考）v1.6 |
| --- | --- | --- |
| `private_MB` ピーク包絡線 | 30s:302 → 90s:597 →（以降）**~600〜705 MB** で高止まり | ~834→660〜893 MB |
| `private_MB` トラフ | 約 150〜296 MB | 約 140〜200 MB |
| `sub_copy_ms` | **44.9 ms** | 45.7 ms |
| `callback_fps` | **17.2** | 17.0 |
| 副モニタ FPS `sub_paint_fps` | **2.94（436 中 76 行が 0）** | 2.93（75 行が 0） |
| `gdi_objects` / `handle_count` 最大 | 136 / 889 | 122 / 889 |

- **プレビュー性能は v1.6 と数値まで一致**（コピー ~45 ms・`callback_fps` ~17・副モニタ飢餓 ~3fps）．v1.7 がプレビュー経路に手を付けていないことをデータが裏付ける．
- **メモリのピーク包絡線は v1.6 の ~890 MB → v1.7 は ~700 MB に低下**（`SaveThread` の Mat 都度 Dispose＋校正時の中間 Mat 解放）．ただしプレビュー経路のリークは残るため，放置区間でも上昇は続き，現行のような平坦な天井にはならない．
- ※ 本プロトコルは単発撮影のため保存経路の差（v1.6→v1.7）は控えめに出る．保存経路単体の効果は連続撮影で顕著になり，自動ベンチの [TEST_03_メモリ修正効果計測](TEST_03_メモリ修正効果計測.md) に隔離計測値がある．

## v1.6 の結果 (v1.6)

データ: [data/perf_v1.6.csv](data/perf_v1.6.csv)（436 サンプル・約 338 秒）．`bench/v1.6`（v1.6 タグに MEMMONITOR 計測スカフォールドを観測フックのみ移植・プレビューのロジックは不変）で基準プロトコルを再現．

### v1.6 固有の計測マッピング

v1.6 は**本モニタが生フレームを直接使いコピーを持たない**ため `main_copy_ms ≈ 0`．毎フレームの全画面 Bitmap コピー（`new Bitmap(bmp)`＝FastClone 前の実装）は**副モニタ用の `sub_copy_ms`** に現れる．FastClone 比較はこの `sub_copy_ms` で読む．

### メモリ（保存経路・プレビュー経路）

| 指標 | 値 |
| --- | --- |
| `private_MB` 開始ベースライン | 約 200 MB |
| `private_MB` ピーク包絡線（30 秒バケットの最大） | 30s:276 → 60s:539 → 90s:**834** MB と上昇し，以降 660〜893 MB で高止まり・大振動 |
| `private_MB` トラフ（谷） | 約 140〜200 MB（GC＋ファイナライザによる周期的一掃） |
| `gdi_objects` / `handle_count` 最大 | 122 / 889（暴走なし） |

- **リークあり＝右肩上がり後に高止まり**．開始 ~200 MB から 90 秒で ~834 MB まで上昇し，以降 140〜890 MB で大きく振動する（毎フレーム `new Bitmap`＝原因1，副モニタ取りこぼしフレームの未 Dispose＝原因2/3 が積み上がり，GC＋ファイナライザが周期的にネイティブメモリを一掃するのこぎり波）．現行の平坦な ~200 MB 天井と対照的．
- GDI/ハンドルは暴走しておらず，原因はネイティブ画素バッファ（メモリ）であることを裏付ける（ハンドル枯渇ではない）．

### プレビュー性能

| 指標 | 値 |
| --- | --- |
| `sub_copy_ms`（`new Bitmap` 全画面コピー） | **平均 45.7 ms**（425 フレーム平均） |
| `main_copy_ms` | 0（v1.6 本モニタはコピーなし） |
| `callback_fps`（ShowImage 実効レート） | 平均 17（最小 ~2） |
| 副モニタ実描画 FPS `sub_paint_fps` | **平均 2.9（436 中 75 行が 0）＝描画飢餓** |

- 全画面コピーが **~46 ms** と重く，コールバックスレッドを律速して `callback_fps` を ~17 に抑える．
- 副モニタは `sub_paint_fps` ≈3（しばしば 0）で**ほとんど描画されない**＝PLAN_03 の副モニタ描画飢餓が旧版で実証された．

## 3 版比較 (Comparison)

3 版すべてを同一基準プロトコル（副モニタ ON）で計測した結果．

| 指標 | **v1.6** | **v1.7** | **現行** |
| --- | --- | --- | --- |
| メモリ `private_MB` 包絡線 | ~200→**834** MB，140〜890 MB で振動 | ~200→**~700** MB，150〜705 MB で振動 | **~180〜200 MB で水平**（撮影時のみ一時 ~450→即復帰） |
| 毎フレーム全画面コピー | `sub_copy_ms` **~46 ms**（`new Bitmap`） | **~45 ms**（同上） | **~2.6 ms**（FastClone） |
| `callback_fps` | ~17（コピー律速） | ~17（同上） | ~30 |
| 副モニタ FPS `sub_paint_fps` | **~3（しばしば 0）＝飢餓** | **~3（同上）** | ~19 で一定 |
| GDI / handle 最大 | 122 / 889 | 136 / 889 | 同程度（枯渇なし） |

### 切り分けの結論 (Conclusion)

改善は 2 経路・2 段階で起きたことが定量的に確認できた．

- **保存経路（メモリ）は v1.6 → v1.7 で改善**: ピーク包絡線が ~890 MB → ~700 MB に低下（`SaveThread`／校正の Mat 解放）．単発撮影プロトコルのため差は控えめだが方向は明確（連続撮影での隔離値は TEST_03）．
- **プレビュー経路は v1.7 → 現行で改善**: コピー ~45 ms → ~2.6 ms（FastClone，約 18 倍），`callback_fps` ~17 → ~30，副モニタ ~3fps（飢餓）→ ~19fps，メモリ包絡線 ~700 MB（上昇）→ ~200 MB（平坦・リーク解消）．v1.6/v1.7 のプレビュー指標が数値まで一致することが，この経路が v1.7 まで未修正だった裏付けになる．
- GDI/ハンドルはどの版も暴走せず，メモリ問題の原因がネイティブ画素バッファ（ハンドル枯渇ではない）であることを 3 版で一貫して確認．

## 関連 (Related)

- 計測計画・指標定義・移植方針: [PLAN_04_性能評価計測計画](../03_PLAN/PLAN_04_性能評価計測計画.md)．
- 自動ベンチによるメモリ計測（別手段・参考）: [TEST_03_メモリ修正効果計測](TEST_03_メモリ修正効果計測.md)．
