73 lines
8.1 KiB
Markdown
73 lines
8.1 KiB
Markdown
# 大容量 PDF の負荷試験記録
|
||
|
||
最新のUI修正後の再測定は [ui-finalの記録](results/ui-final/stress/README.md) を参照してください。[completion-finalの記録](results/completion-final/stress/README.md)と以下は、以前の本体による測定履歴です。資料構造と再現手順は共通です。
|
||
|
||
2026-09-19、Arch Linux x86_64 / kernel 7.2.2-zen1-1-zen / Qt 6.11.2、Xvfb の専用 X11 表示と Qt Quick software rendering で当時のビルドを測定した。画面は 1400×900、アプリ窓は 1100×800、DPR 1。PDFium ワーカーの Landlock/seccomp と資源制限は有効のままである。以下は [stress-final/report.json](results/stress-final/report.json) の結果で、[従来の記録](results/stress/report.json) は旧ビルドの履歴として保持する。
|
||
|
||
## 入力と再現方法
|
||
|
||
`generate_stress_pdf.py` は、オリジナルの紙面テクスチャ・ブロック文字・バーコードを持つ **1,280 個の異なる 512 × 512 RGB 画像**を、フィルターなしの各 768 KiB PDF image stream として書く。5,000 ページの全てに画像を描画し、画像を `pageIndex % 1280` で再利用する。全画像が少なくとも一度参照される。サイズを稼ぐだけの未参照データや padding はない。
|
||
|
||
- PDF サイズ: **1,009,828,104 bytes**(約 963.05 MiB / 0.940 GiB)。
|
||
- 実ラスター payload: **1,006,632,960 bytes**(960 MiB)。
|
||
- SHA-256: `a8657fdaef99e4e6d3eb650bfc4afe9ded74dee4873c69698fcd73021617dc2e`。
|
||
- ページ: 600 × 800 pt。画像矩形: `[44, 180, 556, 692]`。ページ番号・画像番号の本文マーカーと二つの色マーカーを持つ。
|
||
- 生成前空き容量: 318,780,846,080 bytes。出力見積りに加え 512 MiB の余裕を要求する。
|
||
- ラスター用バッファ: テンプレートと現在の画像の計 1.5 MiB。全文書を RAM に保持せず、逐次書き込みと SHA-256 更新を行う。
|
||
|
||
通常のビルド後、次で生成・検査・GUI 試験・削除まで実行する。
|
||
|
||
```sh
|
||
python3 tests/test_stress_generator.py
|
||
python3 tests/test_stress_runner.py
|
||
python3 tests/run_stress_pdf.py --xvfb --binary build/docview --output tests/results/stress-final
|
||
```
|
||
|
||
最初のコマンドは 5 ページ・2 画像のみを使用する軽量試験で、再現性、画像の固有性と参照、xref、空き容量不足、既存ファイル保護を確認する。二番目の新しい runner 回帰は GUI/大容量 PDF を使わず、出力 schema、実 open 数、メモリ圧迫、no-op 除外、close 後解放、起動失敗時の旧集計除去、実行ファイル改変時の失敗を検査する。今回 3 試験が通過し、[軽量試験ログ](results/stress-final/runner-tests.log)を保存した。三番目は `build/stress/` 内の一時ディレクトリに大容量 PDF を作り、成功・失敗のどちらでも回収する。利用者の設定・履歴には一時 XDG ディレクトリを使用する。
|
||
|
||
## 測定結果
|
||
|
||
アプリ自身が focused window にキーイベントを送り、`frameSwapped` で初回応答を記録し、全可視タイルがそろった後のフレームを最終品質とする。これは提示キュー時刻であり、物理ディスプレイの scanout を確認する値ではない。`--benchmark-runs 3 --benchmark-close-cycles 2 --benchmark-operations 100 --benchmark-scroll-steps 0` を明示し、実際に 3 open、操作前の単純 open/close 2 回、操作後の close 1 回を行った。3 回の open は毎回新しいワーカー、100 操作はページ移動 80 回と拡大/fit-width 20 回から成る。キャッシュ分類は位置が変わったページ移動だけを含み、no-op は 0 件だった。継続スクロールはこの有限試験では実施していない。生成直後の OS ファイルキャッシュは残している。
|
||
|
||
| 項目 | 件数 | P50 | P95 | 最大 |
|
||
|---|---:|---:|---:|---:|
|
||
| open → 可視本文の提示 | 3 | 96.71 ms | 97.70 ms | 97.70 ms |
|
||
| キー → 初回応答フレーム | 100 | 6.61 ms | 8.14 ms | 11.69 ms |
|
||
| キー → 全可視タイルの最終品質 | 100 | 12.01 ms | 24.12 ms | 40.35 ms |
|
||
| キャッシュ済みページ移動 | 68 | 11.86 ms | 15.87 ms | 18.87 ms |
|
||
| 新規可視タイルを要するページ移動 | 12 | 18.67 ms | 40.35 ms | 40.35 ms |
|
||
|
||
| メモリ・要求 | 実測 |
|
||
|---|---:|
|
||
| アプリのピーク RSS | 410,173,440 bytes |
|
||
| アプリと子プロセス合計のピーク RSS | 752,041,984 bytes |
|
||
| 各 open 完了時のプロセス合計 RSS | 379,916,288 / 384,729,088 / 386,531,328 bytes |
|
||
| タイルキャッシュのピーク charged bytes | 268,423,168 bytes |
|
||
| タイルキャッシュ上限 | 268,435,456 bytes(256 MiB) |
|
||
| 可視/先読みタイル要求 | 205 / 281 |
|
||
| 描画待ち/queued render/active render の最大 | 4 / 3 / 1 |
|
||
| 破棄済み queued requests | 28 |
|
||
| 最大メモリ圧迫段階 | 0(通常解像度条件を維持) |
|
||
|
||
表はアプリ内の 100 ms 間隔の標本である。独立した 50 ms 間隔の `/proc` 監視はアプリ 413,401,088 bytes、子を含む合計 755,404,800 bytes を観測した。標本時刻が異なるため値は一致しない。合計 RSS は共有ページをプロセスごとに数えるため PSS ではなく、Xvfb は含めない。有限間隔のサンプルなので瞬間的な全ピークを保証しない。
|
||
|
||
全 3 close で Empty とタイル cache 0 を確認した。単純 open/close 2 回後の合計 RSS は 132,026,368 / 134,127,616 bytes、操作後の最終 close は 376,856,576 bytes だった。プロセスの allocator 等に残る RSS を含み、2 回の均一条件だけで長期リークを判定する試験ではない。
|
||
|
||
## 終端ページとクリーンアップ
|
||
|
||
独立した `pdfinfo` が 5,000 ページを認識し、`pdftotext` が 1・1,280・5,000 ページの予定マーカーを抽出した。1,280 個の画像 digest は全て異なる。先頭・中間・末尾の image stream を再読込してハッシュ一致と xref を検査した。アプリが試験後に算出した全文書 SHA-256 も生成時の値と一致した。
|
||
|
||
別プロセスで `--page 5000 --smoke-output ...` を実行し、Ready / pdf、可視 PDF 寸法、viewportReady、PNG/runtime 保存の成功を満たして終了した。[保存画面](results/stress-final/last-page/screen.png)を `view_image` で目視し、`DOCVIEW STRESS PAGE 05000 OF 05000 IMAGE 1159`、ラスター画像、ステータス `5000 / 5000` を確認した。自動 OCR 検証ではない。メモリ圧迫 0 の集計対象は benchmark プロセスであり、smoke の runtime 出力には圧迫段階の時系列は含まれない。
|
||
|
||
証跡は [report.json](results/stress-final/report.json)、[benchmark.json](results/stress-final/benchmark.json)、[source-manifest.json](results/stress-final/source-manifest.json) に保存した。原本 SHA は benchmark 終了時と smoke 後の独立読込の両方で生成時と一致した。大容量 PDF は削除済みで、`sourceRemoved=true` と `build/stress/` に PDF が残っていないことを確認した。全工程 14.291 s、benchmark プロセス 7.468 s、smoke プロセス 4.893 s。
|
||
|
||
次の主 3 実行ファイルは試験前後で SHA-256 が一致した。report の `executableSha256`/`executableSha256After`/`executablesUnchanged` に保存する。
|
||
|
||
| 実行ファイル | SHA-256 |
|
||
|---|---|
|
||
| docview | `9612bccb5ce864174c1898843a90fa75c2598ac47e8abb3b9822d35c78d766c5` |
|
||
| docview-pdf-worker | `b199d491f411dc32c60c5f19bd07c24d0cc85fb5e43ca1f08f085615574dc461` |
|
||
| docview-archive-worker | `312dc77c52f9b40441f339381ae5209cac4d11d8131c9f1f239aa025713f0966` |
|
||
|
||
この試験は大容量・大量ページの取扱い、遠方移動、キャッシュ上限の観測である。3 回の open は 30 回の性能受入条件を置き換えず、仮想表示器は設計書の基準機ではない。1,280 画像を再利用する合成文書は、5,000 ページ全てが異なる高解像度スキャン、圧縮画像の複雑な復号、実書籍の互換性、長時間のリーク検証を網羅しない。
|