# 画面設計書 5-Benchmark Sample

## 概要

本ドキュメントは、.NET WebAssembly のベンチマークサンプル画面「Benchmark Sample」の設計内容を記載した画面設計書です。本画面は .NET Runtime リポジトリにおける WebAssembly のパフォーマンス測定を行うためのベンチマークアプリケーションです。

### 本画面の処理概要

本画面は、ブラウザ上で .NET WebAssembly ランタイムの各種パフォーマンスベンチマーク（JSON シリアライズ、文字列処理、Span 操作、ベクトル演算、JS 相互運用、WebSocket、例外処理、アプリ起動時間）を実行し、結果を測定・表示するサンプルアプリケーションです。

**業務上の目的・背景**：本画面は、.NET WebAssembly ランタイムのパフォーマンス特性を測定・分析するために作成されました。ランタイムの最適化効果の検証、異なるワークロードでの性能比較、リグレッションテストなど、開発者がパフォーマンスを定量的に評価するための基盤を提供します。Jiterpreter 統計、インタープリター PGO データの収集機能も備えており、ランタイム最適化の研究開発にも使用されます。

**画面へのアクセス方法**：ローカル開発サーバーにブラウザでアクセスすることで画面を表示できます。URL パラメータ `?task=TaskName` で実行タスクを指定、`?exclusions=Pattern` で除外パターンを設定できます。

**主要な操作・処理内容**：
1. 画面ロード時に JavaScript（main.js）が .NET WebAssembly ランタイムを初期化
2. URL パラメータからタスク指定と除外パターンを読み取り
3. 各ベンチマークタスクを順次実行（AppStart, Exceptions, Json, Span, String, Vector, JSInterop, WebSocket）
4. 各タスクの実行時間を測定し結果を DOM に表示
5. 全タスク完了後、JSON 形式と HTML 形式で結果をサーバーに送信
6. Jiterpreter 統計と PGO データを保存

**画面遷移**：本画面は単一画面のサンプルアプリケーションであり、他画面への遷移はありません。ただし、AppStart タスクで iframe を使用した画面ロードテストを実行します。

**権限による表示制御**：本画面は認証・認可機能を持たないデモアプリケーションであり、権限による表示制御はありません。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Mono | 主機能 | WebAssembly ランタイム上でベンチマーク処理を実行 |
| 10 | System.Text.Json | 主機能 | ベンチマーク結果の JSON シリアライズ/デシリアライズ |
| 11 | System.Text.RegularExpressions | 主機能 | タスク名のパターンマッチングによるフィルタリング |
| 14 | System.Net.WebSockets | 主機能 | WebSocket 通信のベンチマーク実行 |
| 7 | System.Collections | 補助機能 | ベンチマークタスクとリザルトのコレクション管理 |
| 59 | WebAssembly Workload | 補助機能 | WebAssembly アプリケーションのビルドと実行をサポート |

## 画面種別

ベンチマーク実行・結果表示画面（単一画面）

## URL/ルーティング

- ローカル開発: `http://localhost:8000/index.html`
- タスク指定: `http://localhost:8000/index.html?task=Json&task=String`
- 除外指定: `http://localhost:8000/index.html?exclusions=.*WebSocket.*`
- 静的ファイルパス: `src/mono/sample/wasm/browser-bench/wwwroot/index.html`

## 入出力項目

| 項目名 | 入出力 | データ型 | 説明 |
|--------|--------|----------|------|
| task | 入力(URL) | string | 実行するタスク名（複数指定可） |
| exclusions | 入力(URL) | string | 除外パターン（正規表現、複数指定可） |

## 表示項目

| 項目ID | 項目名 | 要素タイプ | 説明 |
|--------|--------|-----------|------|
| header | 画面タイトル | h3 | 「Wasm Browser Sample - Simple Benchmark」と表示 |
| out | ベンチマーク結果 | span | ベンチマーク実行結果を HTML 形式で表示 |

## イベント仕様

### 1-画面ロード完了イベント

画面がロードされると、以下の処理が自動的に実行されます:

1. `main.js` がモジュールとして読み込まれる
2. `dotnet.create()` で WebAssembly ランタイムを初期化（jiterpreter-stats-enabled）
3. `mainApp.init()` でベンチマーク環境を初期化
4. URL パラメータから `task` と `exclusions` を読み取り
5. `/rewrite=bootstrap.flag` に POST リクエスト送信
6. ベンチマークループ開始（yieldBench で各タスクを実行）
7. 各結果を DOM に追加し `/log=bench-log.txt` に POST
8. 完了後 `/rewrite=results.json` と `/rewrite=results.html` に結果を POST
9. Jiterpreter 統計とインタープリター PGO データを保存

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | 本画面はデータベースを使用しません |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|---------|
| MSG-001 | 情報 | Benchmark started | ベンチマーク開始時 |
| MSG-002 | 結果 | {TaskName}, {MeasurementName} count: {n}, per call: {ms}ms, total: {s}s | 各測定完了時 |
| MSG-003 | 情報 | Finished | 全ベンチマーク完了時 |
| MSG-004 | サマリ | Summary / {TaskName}: {time}ms | 最終サマリー表示時 |

## 例外処理

| 例外種別 | 発生条件 | 対応処理 |
|---------|---------|---------|
| ベンチマーク例外 | タスク実行中のエラー | 例外メッセージを結果に含めて続行 |
| JavaScript エラー | ランタイム初期化失敗時 | `exit(1, err)` で終了 |
| タイムアウト | waitFor で 20 秒経過時 | コンソールにエラー出力して継続 |

## 備考

- `--jiterpreter-stats-enabled` オプションで Jiterpreter 統計を有効化
- `_jiterpreter_dump_stats()` で Jiterpreter 統計をコンソールに出力
- `_interp_pgo_save_data(true)` でインタープリター PGO データを保存
- ベンチマークタスク: AppStart, Exceptions, Json, Span, String, Vector, JSInterop, WebSocket
- 各 Measurement は InitialSamples (10), NumberOfRuns (5), RunLength (5000ms) がデフォルト

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、ベンチマーク結果のデータ構造とタスク定義を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | BenchTask.cs | `src/mono/sample/wasm/browser-bench/BenchTask.cs` | BenchTask 抽象クラスと Result 構造体を確認 |
| 1-2 | Program.cs | `src/mono/sample/wasm/browser-bench/Program.cs` | タスク一覧と JSExport メソッドを確認 |

**読解のコツ**: `BenchTask.Result` クラスで span（実行時間）、steps（実行回数）、taskName、measurementName が定義されています。

#### Step 2: エントリーポイントを理解する

処理の起点となるファイル・関数を特定します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.html | `src/mono/sample/wasm/browser-bench/wwwroot/index.html` | HTML 構造と style.css 参照を確認 |
| 2-2 | main.js | `src/mono/sample/wasm/browser-bench/wwwroot/main.js` | MainApp クラスとベンチマークループを確認 |

**主要処理フロー (main.js)**:
1. **49-76行目**: `MainApp.init()` - ベンチマーク環境初期化
2. **78-86行目**: URL パラメータ処理（task, exclusions）
3. **94-103行目**: ベンチマークループ（yieldBench で順次実行）
4. **106-115行目**: 結果の POST 送信（results.json, results.html）
5. **121-130行目**: Jiterpreter 統計と PGO データ保存

#### Step 3: ベンチマークタスクの実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Program.cs | `src/mono/sample/wasm/browser-bench/Program.cs` | RunBenchmark と結果集計処理を確認 |
| 3-2 | Json.cs | `src/mono/sample/wasm/browser-bench/Json.cs` | JSON ベンチマークタスク実装例 |

**主要処理フロー (Program.cs)**:
- **23-33行目**: タスク一覧定義（AppStart, Exceptions, Json, Span, String, Vector, JSInterop, WebSocket）
- **37-41行目**: `RunBenchmark` - タスク実行メイン処理
- **109-128行目**: `NextTask` - 次のタスクに進む
- **130-158行目**: `NextMeasurement` - 次の測定に進む
- **160-180行目**: `RunTasks` - 実際のベンチマーク実行
- **182-211行目**: `ResultsSummary` - 結果サマリー生成

### プログラム呼び出し階層図

```
[Browser] index.html 読み込み
    |
    +-- [JavaScript] main.js 実行
            |
            +-- dotnet.create() - WebAssembly ランタイム初期化
            |       |
            |       +-- --jiterpreter-stats-enabled オプション
            |
            +-- mainApp.init(runtime)
                    |
                    +-- getAssemblyExports() - C# メソッドを取得
                    |
                    +-- setModuleImports() - JS 関数を公開
                    |
                    +-- URL パラメータ処理
                    |       |
                    |       +-- setTasks(tasks) - タスク設定
                    |       +-- setExclusions(exclusions) - 除外設定
                    |
                    +-- POST /rewrite=bootstrap.flag
                    |
                    +-- ベンチマークループ
                            |
                            +-- yieldBench() - タスク実行
                            |       |
                            |       +-- [C#] RunBenchmark()
                            |               |
                            |               +-- RunTasks()
                            |                       |
                            |                       +-- NextTask() / NextMeasurement()
                            |                       |
                            |                       +-- Task.RunBatch()
                            |                               |
                            |                               +-- Measurement.RunBatch()
                            |
                            +-- DOM 更新 (#out)
                            |
                            +-- POST /log=bench-log.txt
                            |
                            +-- (ループ継続)
                    |
                    +-- POST /rewrite=results.json
                    |
                    +-- POST /rewrite=results.html
                    |
                    +-- _jiterpreter_dump_stats()
                    |
                    +-- _interp_pgo_save_data(true)
```

### データフロー図

```
[入力]                      [処理]                           [出力]

URL パラメータ
  ?task=Json,String -----> setTasks() -----> Instance.tasks 更新
  ?exclusions=.*WS.* ----> setExclusions() -> exclusionPatterns 更新

                     +-- RunBenchmark() ----+
                     |                      |
                     v                      v
              NextTask()            NextMeasurement()
                     |                      |
                     +----------+-----------+
                                |
                                v
                     Measurement.RunBatch()
                                |
                     +----------+-----------+
                     |                      |
                     v                      v
              RunStep() x N回         計測時間記録
                     |                      |
                     +----------+-----------+
                                |
                                v
                          Result 生成
                                |
                     +----------+-----------+
                     |          |           |
                     v          v           v
              DOM 表示    bench-log.txt   results.json
               (#out)     (POST)          (POST)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.html | `src/mono/sample/wasm/browser-bench/wwwroot/index.html` | テンプレート | HTML エントリーポイント |
| main.js | `src/mono/sample/wasm/browser-bench/wwwroot/main.js` | ソース | JavaScript エントリーポイント、MainApp クラス |
| style.css | `src/mono/sample/wasm/browser-bench/wwwroot/style.css` | スタイル | スタイルシート |
| Program.cs | `src/mono/sample/wasm/browser-bench/Program.cs` | ソース | メインロジック、結果集計 |
| BenchTask.cs | `src/mono/sample/wasm/browser-bench/BenchTask.cs` | ソース | ベンチマークタスク基底クラス |
| Json.cs | `src/mono/sample/wasm/browser-bench/Json.cs` | ソース | JSON ベンチマークタスク |
| String.cs | `src/mono/sample/wasm/browser-bench/String.cs` | ソース | 文字列ベンチマークタスク |
| Span.cs | `src/mono/sample/wasm/browser-bench/Span.cs` | ソース | Span ベンチマークタスク |
| Vector.cs | `src/mono/sample/wasm/browser-bench/Vector.cs` | ソース | ベクトル演算ベンチマークタスク |
| JSInterop.cs | `src/mono/sample/wasm/browser-bench/JSInterop.cs` | ソース | JS 相互運用ベンチマークタスク |
| WebSocket.cs | `src/mono/sample/wasm/browser-bench/WebSocket.cs` | ソース | WebSocket ベンチマークタスク |
| Exceptions.cs | `src/mono/sample/wasm/browser-bench/Exceptions.cs` | ソース | 例外処理ベンチマークタスク |
| AppStart.cs | `src/mono/sample/wasm/browser-bench/AppStart.cs` | ソース | アプリ起動ベンチマークタスク |
