ユーザーが受け入れ基準を最初に定義することでLLMの効果が最大化される
概要
- LLM生成のRust製データベースは、SQLiteと比べて極端に遅いことが判明
- コードは正しく動作し、テストも合格するが、根本的な設計ミスで実用性に乏しい
- 性能劣化の原因は、クエリプランナーやトランザクション管理など複数のバグと安全志向の設計判断
- LLMは「もっともらしさ」を優先し、本質的な要件や最適化を見落とす傾向
- 表面上は正しいが本質的に不適切な実装が生まれるリスクを検証
LLM生成Rustデータベースの性能問題
- SQLiteとLLM生成Rust実装で100件の主キー検索を比較
- SQLite:0.09 ms
- LLM Rust版:1,815.43 ms(約20,171倍遅い)
- Turso/libsqlとは無関係なプロジェクトであり、TursoはSQLiteのCコードベースをフォークしたもの
- TursoのベンチマークはSQLiteの1.2倍程度で、成熟したフォークとして妥当な性能
コードの外観と実態
- Rust実装は動作し、テストも合格
- SQLiteファイルフォーマットを読み書き可能
- READMEにはMVCC、C API互換、ファイル互換性を謳う
- 実際は著しく遅く、運用に耐えない
LLM生成コードの失敗パターン
- LLMは「もっともらしさ」を最優先
- 正しく見えるが実用性や最適化が欠如
- 受け入れ基準を事前に明確化することが重要
- 他の研究(METR, GitClear)でも同様の傾向が確認されている
主な性能劣化の原因
- 主キー検索がB-tree検索にならない
- id INTEGER PRIMARY KEYがrowidとして認識されず、全件スキャン(O(n²))
- SQLiteはWHERE id = NでO(log n)のB-tree検索を実現
- Rust実装はWHERE rowid = ?のみ高速経路
- INSERT時に毎回fsyncを実行
- トランザクション外のINSERTごとにフル同期
- SQLiteはfdatasync(メタデータ同期省略)をデフォルト使用し高速化
細かな性能低下要因
- ASTクローンの多用:SQLパース済みASTを毎回複製・再コンパイル
- ヒープアロケーション乱用:キャッシュヒットでも4KB Vec<u8>を新規確保
- スキーマの毎回リロード:autocommitごとに全CREATE TABLEを再パース
- ホットパスでの不要なフォーマット:毎回SQL文字列へ変換
- オブジェクトの逐次生成破棄:トランザクションやVDBEなどを毎回生成・破棄
安全志向の設計判断の弊害
- Rust所有権や安全性を重視した結果、極端な性能低下
- SQLiteの高速化はC言語だけでなく、26年の最適化の積み重ね
過剰設計の別事例
- ビルドアーティファクト削除のための巨大なRustプロジェクト
- 82,000行、192依存、36,000行のダッシュボードなど
- 実際にはcronの1行ジョブで十分
- cargo-sweepやOS標準の回復手段も未活用
LLM生成コードの本質的な問題
- 「求められたもの」を忠実に生成するが、「本当に必要なもの」とは限らない
- 表面的には正しく、テストもパスするが、本質的要件や最適化を満たさない
- 問題の本質は構文や文法の誤りではなく、要件や最適化の見落とし
まとめと教訓
- LLM活用時は受け入れ基準・ベンチマーク・設計意図の明確化が不可欠
- 「見た目が正しい」だけではなく、「本当に正しい」かを検証する仕組みの重要性
- 安全志向や最新技術の導入が、必ずしも実用性や効率性に直結しない事例