> For AI agents: the complete documentation index is available at https://renmori.mewbaka.cn/ja/llms.txt, the full documentation bundle is available at https://renmori.mewbaka.cn/ja/llms-full.txt.

# 実ゲームでの実測

本ページは、実在する GalGame の配布用ビルドで RenMori 1.2.0 を実測した結果を記録したものです。同一ビルドのオリジナル版と RenMori フル保護版を同じデバイス上で比較し、シーケンシャル読み込みのスループット、ランダム読み込みのレイテンシ、コールドスタートのレイテンシを測定しました。保護版はプレイヤーが実際に起動するときと同じく、ネイティブ launcher を経由して起動しています。

[パフォーマンスベンチマーク](https://renmori.mewbaka.cn/ja/milestones/benchmark.md) の合成アセットとは異なり、本ページのサンプルは実在する作品の配布用ビルドで、CG、立ち絵、UI 素材、BGM、ボイス、動画を含む約 3.5 GB のアセットから成ります。作品名は本ページでは公開しません。

## 結果の要約

プレイヤーにとって、暗号化はほとんど体感できません。

- ランダム読み込みで増える遅延は最大でも約 0.15 ms で、60 FPS での 1 フレーム（16.7 ms）の 1% に満たない
- コールドキャッシュでの全アセットのシーケンシャル読み込みスループットは 584 MB/s で、リアルタイムの音声・動画デコードに必要な帯域の 100 倍以上
- 平均的な大きさ（約 1.9 MB）の画像 1 枚の読み込み時間は、コールドキャッシュで約 1.8 ms 増えるのみで、Ren'Py は通常バックグラウンドで画像を先読みする
- コールドスタートから最初のフレームまでの時間は 7.16 s から 8.44 s に増加。増えた 1.3 s は起動時に一度だけ発生し、プレイ中には発生しない
- 保護版の `game/` ディレクトリのサイズ増加はわずか 0.09% で、3 プラットフォーム分のネイティブランタイムを含む

## テスト環境

| 項目      | 値                                                 |
| ------- | ------------------------------------------------- |
| テスト日    | 2026-10-31                                        |
| デバイス    | Apple M1、メモリ 8 GB、内蔵 SSD                          |
| OS      | macOS 26.5.1（arm64）                               |
| Ren'Py  | 8.5.2.26010301                                    |
| RenMori | 1.2.0、フル保護（poly）、lockdown 有効、ネイティブ launcher 経由で起動 |

## テストサンプル

オリジナル版は作品の配布用ビルドで、`game/` ディレクトリは合計 3.51 GiB です。アセットは 2.05 GiB の RPA アーカイブと 2 つの独立した動画ファイルに格納されています。保護版は同じビルドから `renmori protect` で生成したもので、すべてのアセットが暗号化コンテナ `renmori.rmc` に格納されています。

比較対象は両ビルドに存在し、かつサイズが一致するエントリのみで、合計 1407 件、3593 MB です。コンパイル済みスクリプト 22 件（`.rpyc` と `.rpymc`）は保護版でスクリプト層の変換を受けてサイズが異なるため、読み込みテストから除外しています。

| カテゴリ  | ファイル数 |      合計 |
| ----- | ----: | ------: |
| 画像    |   774 | 1477 MB |
| 音声    |   599 |  540 MB |
| 動画    |     2 | 1497 MB |
| スクリプト |    21 |  0.3 MB |
| その他   |    11 |   79 MB |
| 全体    |  1407 | 3593 MB |

本ページの MB はすべて 2<sup>20</sup> バイトを指します。

## テスト方法

すべての測定はエンジンのプロセス内で行い、エンジン自身の読み込み経路である `renpy.loader.load` を通じて読み込んでいます。そのため、保護版の数値には復号、認証、コンテナインデックスの検索にかかるすべてのオーバーヘッドが含まれます。両ビルドとも `.app` 内の実行ファイルを直接起動しており、保護版は launcher の起動処理を経由します。

### コールドキャッシュとウォームキャッシュ

コールドキャッシュの測定のたびに、APFS クローン（`cp -c`）でビルドの新しいコピーを作成しています。クローンはディスク上のデータを元のファイルと共有しますが、OS からは新しいファイルとして扱われ、その内容はページキャッシュに一切存在しないため、各ファイルの最初の読み込みは必ずディスクにアクセスします。事前の確認では、クローン直後の 1 回目のランダム 4 KB 読み込みの中央値が 104 µs、2 回目が 1.4 µs となり、1 回目が確かにコールドキャッシュであることを確認しました。

ウォームキャッシュの測定は同じクローン上で読み込みを繰り返すもので、データはすでにページキャッシュにあるため、結果は CPU のオーバーヘッドのみを反映します。

### 測定項目

| 項目                | 方法                                                                                              |
| ----------------- | ----------------------------------------------------------------------------------------------- |
| シーケンシャル読み込み       | 1407 件のエントリすべてを 1 MB 単位で最後まで読み込む。1 回目はコールド、2〜4 回目はウォームでその中央値を採用。毎回新しいクローンを使って 3 回実施             |
| ランダム 4 KB / 64 KB | 最大の 64 ファイル（いずれも 4 MB 以上、合計 2214 MB）からファイルとオフセットをランダムに選び、シーク後に 4 KB または 64 KB を読み込む。各 2000 サンプル |
| 小さなファイルのランダムオープン  | 256 KB 以下の 822 ファイルからランダムに選び、開いて最後まで読み込む。1000 サンプル                                              |
| コールドスタート          | 実行ファイルの起動から、エンジンが最初のフレームを描画するまで。コールドスタートは毎回新しいクローンで 5 回、ウォームスタートは同じクローンで 1 回の予備起動の後に 5 回測定      |

ランダム読み込みのコールドとウォームは同じ乱数系列を使い、3 回分の全サンプルをまとめて中央値と p95 を算出しています。

## 結果

### シーケンシャル読み込み

単位は MB/s、値が大きいほど良好です。

| カテゴリ  | オリジナル版（コールド） | 保護版（コールド） | オリジナル版（ウォーム） | 保護版（ウォーム） |
| ----- | -----------: | --------: | -----------: | --------: |
| 画像    |         1154 |       555 |         1302 |       480 |
| 音声    |         1132 |       430 |         1022 |       480 |
| 動画    |         1895 |       658 |         2281 |       557 |
| スクリプト |          118 |        85 |           96 |        75 |
| その他   |         1644 |       568 |         1621 |       458 |
| 全体    |         1303 |       584 |         1547 |       419 |

保護版のスループットは、コールドキャッシュでオリジナル版の約 45%、ウォームキャッシュで約 27% です。ウォームキャッシュではディスク待ちがなくなるため、保護版の約 420〜560 MB/s が現時点での復号の上限となります。

コールドキャッシュのスループットで換算すると、平均的な大きさ（約 1.9 MB）の画像 1 枚の読み込みにかかる時間は、オリジナル版で約 1.6 ms、保護版で約 3.4 ms です。動画と BGM はエンジンがストリーミングで読み込み、そのビットレートは通常毎秒数 MB 程度で、584 MB/s とは 2 桁以上の差があります。

### ランダム読み込み

単位は ms、値が小さいほど良好です。

| テスト              | キャッシュ | オリジナル版 中央値 | 保護版 中央値 | オリジナル版 p95 | 保護版 p95 |
| ---------------- | ----- | ---------: | ------: | ---------: | ------: |
| ランダム 4 KB        | コールド  |      0.216 |   0.181 |      0.443 |   0.399 |
| ランダム 4 KB        | ウォーム  |      0.200 |   0.187 |      0.479 |   0.456 |
| ランダム 64 KB       | コールド  |      0.252 |   0.403 |      0.452 |   0.760 |
| ランダム 64 KB       | ウォーム  |      0.249 |   0.348 |      0.397 |   0.699 |
| 小さなファイルのランダムオープン | コールド  |      0.196 |   0.265 |      0.937 |   0.988 |
| 小さなファイルのランダムオープン | ウォーム  |      0.100 |   0.143 |      0.438 |   0.675 |

ランダム 4 KB 読み込みは両者同等で、差は測定誤差の範囲内です。ランダム 64 KB 読み込みの中央値は 0.10〜0.15 ms 増えますが、これは 64 KB の読み込みが通常 2 つのチャンクにまたがり、両方を復号・認証する必要があるためです。小さなファイルのランダムオープンの中央値は 0.04〜0.07 ms 増え、これはコンテナインデックスの検索とファイルごとの鍵導出によるものです。

### コールドスタート

単位は s で、実行ファイルの起動から計測した中央値です。括弧内は最小値と最大値です。

| 段階             | キャッシュ |          オリジナル版 |             保護版 |     差 |
| -------------- | ----- | --------------: | --------------: | ----: |
| アセットインデックス準備完了 | コールド  | 3.13（2.46–3.82） | 3.18（2.80–3.74） | +0.05 |
| 最初のフレームを描画     | コールド  | 7.16（6.01–7.70） | 8.44（7.99–9.04） | +1.28 |
| アセットインデックス準備完了 | ウォーム  | 0.97（0.72–1.07） | 0.76（0.65–1.33） | −0.21 |
| 最初のフレームを描画     | ウォーム  | 5.05（3.82–6.50） | 5.83（4.61–6.54） | +0.78 |

launcher の起動処理とコンテナインデックスの構築による時間の増加はほとんどなく、コールドキャッシュでアセットインデックスの準備が完了するまでの差はわずか 0.05 s です。ウォームスタートは回ごとのばらつきが大きいため、両者の差はコールドスタートの数値を基準とします。

増加した時間はスクリプトの読み込み段階に集中しています。保護版はディスク上に平文を残さないよう、バイトコードや画面解析などの Ren'Py のランタイムキャッシュを書き込まないため、起動のたびにスクリプト内の Python コードを再コンパイルします。1 回の実行における Ren'Py のログでは、「Loading script」段階はオリジナル版で 169 ms、保護版で 1967 ms でした。

### サイズのオーバーヘッド

| ビルド    |      `game/` のサイズ |
| ------ | ----------------: |
| オリジナル版 | 3,768,321,012 バイト |
| 保護版    | 3,771,724,069 バイト |
| 差      |            +0.09% |

保護版のサイズには、暗号化コンテナ、ランタイムローダー、Windows、Linux、macOS の 3 プラットフォーム分のネイティブランタイムが含まれます。暗号化コンテナのみでは、オリジナル版のアセットに対するオーバーヘッドは 0.08% です。

## 結果の解釈

プレイヤーが体感するパフォーマンスの問題は、主にカクつきと待ち時間です。カクつきは 1 回の読み込みが 1 フレーム内に終わるかどうか、待ち時間は大きなアセットが間に合うかどうかで決まります。ランダム読み込みで増える遅延は最大でも約 0.15 ms で 1 フレームの 1% に満たず、シーケンシャルのスループットはコールドキャッシュでも音声・動画のストリーミング再生に必要な帯域を大きく上回ります。プレイ中に暗号化が体感できるカクつきや待ち時間を生むことはありません。

体感できる唯一の差は起動時に増える約 1 s で、平文キャッシュを書き込まないというセキュリティ上のトレードオフによるものであり、起動のたびに一度だけ発生します。

## 制限事項

- 実際のプレイ中のフレーム時間は測定していない。本ページのデータはアセットの読み込みのみを対象とし、画像デコード、音声デコード、レンダリングは含まない
- テストは Apple M1 デバイス 1 台のみで実施しており、Windows、Linux、Steam Deck でのデータは未測定
- テストデバイスは内蔵 SSD を使用している。HDD ではコールドキャッシュの読み込みがディスク速度に強く制約され、保護版とオリジナル版の相対的な差は通常小さくなる
- ウォームスタートの数値はばらつきが大きく、参考値にとどまる
- サンプル作品と測定コードは非公開のため、本ページのデータを第三者が直接再現することはできない。再現可能な合成ベンチマークは [パフォーマンスベンチマーク](https://renmori.mewbaka.cn/ja/milestones/benchmark.md) を参照
