HHVM型チェッカーを掌握せよ:大規模モノレポにおけるIncremental Checkの極限最適化
Hackの型チェッカー(`hh_client` / `hh_server`)は、単なる静的解析ツールではない。あれは、数百万行におよぶAST(抽象構文木)の海を、差分のみを糧にして数秒で渡り切るための、高度に最適化されたグラフ探索エンジンだ。
大規模モノレポにおいて型チェック時間が数分、あるいは十数分に及んでいるなら、それはあなたのコードが「型チェッカーを迷わせている」からに他ならない。本稿では、HHVMの内部メカニズムを逆手に取り、型システムの計算量を最小化するアーキテクチャの極意を伝授する。
—
1. 依存グラフの「崩壊」を防ぐ:型定義の局所化
HHVMの型チェッカーは、依存関係の変更が波及する「影響範囲(Fan-out)」を最小化するように設計されている。しかし、開発者が何も考えずに定義ファイルを肥大化させると、この最適化は無力化する。
なぜ「神クラス」がボトルネックになるのか
例えば、モノレポのあらゆる場所でインポートされる `CommonTypes.php` を想像してほしい。このファイルに新しい型定義を追加、あるいは変更を加えた瞬間、チェッカーは「依存する全ファイルの再評価」をスケジューリングする。
対策:型定義の「垂直分割」
単一の巨大な型定義ファイルではなく、機能ドメインごとに細分化し、型推論のスコープを物理的に隔離せよ。
// 悪い例: 依存の爆発を招く
// 全てのファイルがこのファイルを読み込むため、変更のたびに全ビルドが走る
type CommonTypes = shape(‘id’ => int, ‘meta’ => Map
// 良い例: 必要な箇所にのみ依存を限定
// UserDomain.hack にのみ定義し、アクセス権限を制限する
namespace App\Domain\User;
type UserRecord = shape(‘id’ => int);
2. `HH\FIXME` を撲滅し、型推論の「計算量」を制御する
型チェッカーの深部では、ユニフィケーション(型結合)アルゴリズムが動いている。複雑なジェネリクスや `mixed` 型の多用は、ユニフィケーションの探索空間を指数関数的に増大させる。
隠された計算コスト:ジェネリクスの深いネスト
`Map
- 最適化戦術:
- Type Aliasingの多用: 中間型に名前をつけ、チェッカーが「memoization(メモ化)」を効かせやすくする。
- Strict Modeの徹底: `__Strict` モードでコンパイルし、不確定な型を排除する。`HH\FIXME` で逃げることは、チェッカーに「ここは未解決のまま残せ」という重い負債を強いる行為に等しい。
—
3. HHVMサーバーを「意識」したファイル配置戦略
HHVMのアーキテクチャでは、`hh_server` はメモリ上に抽象構文木の完全なグラフを保持している。このグラフの更新を最適化するには、ファイルシステムとサーバーの同調が不可欠だ。
`.hhconfig` の魔術:`ignored_paths` の最適化
大規模モノレポでは、型チェックが不要なディレクトリ(オートロード用のビルド成果物や、外部ライブラリの不要なサブセット)を徹底的に除外せよ。
.hhconfig の最適化設定例
不要なパスを監視対象から外すことで、ファイルシステムの変更通知(inotify)の負荷を劇的に下げる
ignored_paths =
./vendor/.
./tests/data/.
./generated/.
—
4. 伝説のアーキテクトが教える、真のパフォーマンス・チューニング
型チェックが遅いと感じた時、あなたが確認すべきは「型推論のループ」だ。循環依存(Circular Dependency)はチェッカーの天敵である。
アーキテクチャの防衛線:循環依存の排除
AがBに依存し、BがAに依存するような構造は、チェッカーの反復回数を意図的に増加させる。
// 循環依存の温床例
class A { public function getB(): B { … } }
class B { public function getA(): A { … } }
// 解決策: インターフェースによる分離
interface AInterface { public function getB(): BInterface; }
class A implements AInterface { … }
このようにインターフェースを間に挟むことで、チェッカーは「具象型を追わずにインターフェースの整合性だけを確認する」という軽量な処理へ切り替わることができる。これが、数千万行を捌くためのアーキテクチャの真髄だ。
—
結論:型チェッカーは「敵」ではなく「鏡」である
あなたが書くHackのコードは、型チェッカーという巨大な機械に対する「指示書」だ。その指示書が曖昧であればあるほど、機械は計算に苦しみ、時間は溶けていく。
- 型定義を分割せよ。
- ジェネリクスを単純化せよ。
- 循環依存を徹底的に叩き潰せ。
HHVMの型システムを掌握することは、言語の挙動を支配することと同義だ。さあ、今すぐ `hh_client –ide-check` を走らせ、あなたのコードベースの「無駄な計算」を削ぎ落とせ。それが、最高峰のエンジニアが歩む道だ。