View on GitHub

cat-plugin-player

cat-plugin-player

起動時間の計測

CAT_STARTUP_TRACE に出力先を指定すると、起動処理の各時点をCSVに記録する。 未指定なら記録しない。計測の有無で起動順序や自動演奏の条件は変わらない。

PowerShellでリポジトリのルートから実行する例(Releaseビルド済みの場合):

$env:CAT_STARTUP_TRACE = Join-Path (Get-Location) 'target/startup.csv'
try {
    & ./target/release/cat-plugin-player.exe
} finally {
    Remove-Item Env:CAT_STARTUP_TRACE
}
Get-Content ./target/startup.csv

出力先の親ディレクトリは事前に作成する。同名ファイルは上書きする。 通常は最初の信号生成と背景走査の両方が完了した後のUI更新で保存する。未完了なら10秒経過後の UI更新、または正常終了時に途中までの結果を保存する。 UIスレッドが停止している間やプロセスが強制終了された場合は保存できない。 各計測点はプロセス中の初回のみを記録するため、比較にはアプリを起動し直す。

2026-10-06の変更前の結果

Windows、Release版、履歴のSurge XT(CLAP、org.surge-synth-team.surge-xt)を自動復元。 同一環境で3回連続起動。OSのキャッシュを消す操作は行っていないため、コールド起動の保証はない。 計測ログは target/startup-profiles/run-1.csv ~ run-3.csv(git管理外)。

区間(ms) 1回目 2回目 3回目
main → App生成開始(GUI等の初期化) 241.529 238.973 248.787
App生成開始 → 走査要求(ホスト・デバイス・履歴) 9.056 8.582 8.459
走査要求 → 完了通知 603.173 553.046 561.187
完了通知 → ロード要求(一覧取得・履歴照合) 0.016 0.015 0.028
ロード要求 → 生成完了通知 522.077 509.006 512.885
生成完了通知 → 最初の信号生成 24.077 19.816 20.045
main → 最初の信号生成 1399.928 1329.438 1351.391

主な待ち時間は走査とプラグイン生成。生成API呼び出し自体が507~520msを占め、 そこから生成完了通知までの待ちは約2msだった。 音声ストリーム構築は約19~23ms、デバイス照会は約8ms。

次の改善候補は、前回の1件を直接生成し、全体走査を発音後へ移すこと。 現在の経路から走査時間だけを差し引くと約0.78~0.80秒になるが、これは計算上の参考値であり、 変更後の実測値ではない。直接生成の追加コスト、プラグインロードのキャッシュ状況、 背景走査との競合などで変わる。

さらに短縮する場合は約0.24秒のGUI初期化より前に必要な音声準備を始める構成を検討する。 プラグインのメインスレッド要件は維持する。 観測された「exe起動から約2秒」との差は今回の計測だけでは特定できず、 OSローダーや実際の出力遅延を含めた別の計測が必要。

GUI・全体走査を発音後に移した結果

同じRelease版・Surge XTで再計測。旧履歴からの移行起動を1回行った後、3回連続で起動。 ログは target/startup-profiles/fast-1.csv ~ fast-3.csv。

mainからの経過時間(ms) 1回目 2回目 3回目
最初の信号生成 597.676 557.234 556.114
GUI初期化開始 598.771 558.094 556.704
GUIのApp生成 843.759 786.714 785.376
背景走査開始 846.643 789.756 788.521
一覧取得完了 1415.557 1347.672 1413.321

信号生成の中央値は1351.391msから557.234msへ、約794ms(59%)短縮した。 これは連続起動での比較であり、OSキャッシュを消したコールド起動の結果ではない。 一覧取得が完了する前から演奏できる。GUI初期化は同じメインスレッド上で発音後に行い、 描画器を別スレッドへ移したわけではない。

起動時は保存したバンドルパス・形式・ID・表示情報から1件だけ生成する。 旧形式の履歴、ファイル消失、直接生成失敗時はGUIを開き、走査後に形式・IDで復元を試す。 成功した演奏の履歴にはバンドルパスも保存されるため、旧形式からは通常1回の起動で移行する。

GUI生成前にはshimタスクとWindowsメッセージを処理し、最初の音声コールバックが 処理を終えるのを待つ。無音の音色でもGUIを止めないよう、非ゼロ信号自体は待たない。 非同期の生成・音声開始を待つループは2秒でGUIへ引き継ぐ。 プラグイン内部の同期呼び出しが長時間ブロックする場合は、この制限では中断できない。 GUI初期化中のメインスレッド要求は初期化後に処理されるため、全プラグインでの互換性を 保証するものではない。

背景走査用のホストと、各演奏インスタンスのカタログ情報・形式オブジェクトを分離した。 一覧更新による参照切れや、古いパスを保持した形式キャッシュの再利用を防ぐ。 プラグインの生成・UI・破棄は引き続き同じメインスレッドで行う。

検証: cargo fmt --check、cargo clippy --all-targets -- -D warnings、cargo test、 cargo build --release。実機の補助確認は python tests/native_startup_smoke.py。 後者はPython 3.11以降と、演奏・UI表示ができるインストール済み音源の新形式の履歴を必要とする。 音声はメモリ上で生成し、エディタを一度開閉する。履歴ファイルは変更しない。 欠落パス・生成失敗、演奏中の2回の一覧再取得、再ロード、エディタ開閉、削除、 走査中の終了を確認する(強制フルスキャンは行わない)。

アプリ本体でも、保存パスを一時的に存在しないパスへ変更し、通常走査→ロード→信号生成と 履歴パスの修復を確認した。検証終了後は元の履歴ファイルを復元済み。