Agent skill
performance-diff
変更前後のパフォーマンスを比較し、リグレッションを検出
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/performance-diff
SKILL.md
civicship-api パフォーマンス比較
コード変更前後のパフォーマンスを比較し、リグレッション(性能劣化)を検出します。ベンチマーク結果、クエリ数、レスポンスタイムを分析します。
使用方法
# PRのパフォーマンス比較(自動)
/performance-diff --pr 123
# ブランチ間の比較
/performance-diff --before main --after feature/point-expiration
# 特定ドメインの比較
/performance-diff wallet --before HEAD~1 --after HEAD
引数:
$ARGUMENTS: ドメイン名、PRでは番号、または--before/--afterオプション
パフォーマンス比較プロセス
ステップ1: 変更内容の取得
GitでのDiffを取得:
# PRの差分取得
gh pr diff 123
# ブランチ間の差分
git diff main..feature/point-expiration
# 変更されたファイルのみ
git diff --name-only main..feature/point-expiration
変更サマリー:
## 変更概要
### 変更されたファイル(10ファイル)
**Application Layer:**
- `src/application/domain/account/wallet/service.ts` (+50, -10)
- `src/application/domain/account/wallet/usecase.ts` (+20, -5)
- `src/application/domain/account/wallet/data/repository.ts` (+30, -8)
**Infrastructure Layer:**
- `prisma/schema.prisma` (+5, -0)
**Presentation Layer:**
- `src/application/domain/account/wallet/schema/type.graphql` (+10, -0)
---
### 変更の種類
- [ ] データベーススキーマ変更(カラム追加)
- [ ] 新しいクエリ追加
- [ ] ビジネスロジック変更
- [ ] GraphQL API拡張
ステップ2: パフォーマンステストの実行
変更前後でベンチマークを実行:
# 変更前(main)のパフォーマンステスト
git checkout main
pnpm test:performance > performance-before.txt
# 変更後(feature branch)のパフォーマンステスト
git checkout feature/point-expiration
pnpm test:performance > performance-after.txt
# 差分比較
diff performance-before.txt performance-after.txt
パフォーマンステスト結果:
## パフォーマンステスト結果
### Test: GraphQL Query `wallet(id: "...")`
#### 変更前(main)
\`\`\`
Requests: 1000
Success: 1000 (100%)
Duration: 5.2s
Avg: 5.2ms
P50: 4.8ms
P95: 8.5ms
P99: 12.3ms
\`\`\`
#### 変更後(feature/point-expiration)
\`\`\`
Requests: 1000
Success: 1000 (100%)
Duration: 5.5s
Avg: 5.5ms (+5.8%)
P50: 5.0ms (+4.2%)
P95: 9.0ms (+5.9%)
P99: 13.1ms (+6.5%)
\`\`\`
**評価:** 🟡 軽微な劣化(+5.8%)
**原因:** 有効期限チェックの追加(日付比較)
**許容範囲:** ✅ Yes(+10%以内)
---
### Test: GraphQL Mutation `walletCreate`
#### 変更前
\`\`\`
Requests: 100
Duration: 2.1s
Avg: 21ms
\`\`\`
#### 変更後
\`\`\`
Requests: 100
Duration: 2.3s
Avg: 23ms (+9.5%)
\`\`\`
**評価:** 🟡 軽微な劣化(+9.5%)
**原因:** expiresAt カラムの書き込み追加
**許容範囲:** ✅ Yes(+10%以内)
---
### Test: Batch Process `expirePoints`
#### 変更前
\`\`\`
該当なし(新規処理)
\`\`\`
#### 変更後
\`\`\`
Wallets Processed: 1000
Duration: 8.5s
Avg per wallet: 8.5ms
\`\`\`
**評価:** 🟢 新規処理(ベースラインとして記録)
ステップ3: クエリ数の比較
SQLクエリ数の変化を分析:
## クエリ数の比較
### GraphQL Query `wallet(id: "...")`
#### 変更前
\`\`\`
SELECT * FROM t_wallets WHERE id = '...' -- 1クエリ
\`\`\`
**Total:** 1クエリ
---
#### 変更後
\`\`\`
SELECT * FROM t_wallets WHERE id = '...' -- 1クエリ
\`\`\`
**Total:** 1クエリ(変更なし)
**評価:** ✅ クエリ数増加なし
---
### GraphQL Mutation `pointTransfer`
#### 変更前
\`\`\`
1. SELECT * FROM t_wallets WHERE userId = 'from-user'
2. SELECT * FROM t_wallets WHERE userId = 'to-user'
3. UPDATE t_wallets SET balance = ... WHERE id = 'from-wallet'
4. UPDATE t_wallets SET balance = ... WHERE id = 'to-wallet'
5. INSERT INTO t_point_transactions ...
\`\`\`
**Total:** 5クエリ
---
#### 変更後
\`\`\`
1. SELECT * FROM t_wallets WHERE userId = 'from-user'
2. SELECT * FROM t_wallets WHERE userId = 'to-user'
(有効期限チェック追加: メモリ内で実行、クエリ不要)
3. UPDATE t_wallets SET balance = ... WHERE id = 'from-wallet'
4. UPDATE t_wallets SET balance = ... WHERE id = 'to-wallet'
5. INSERT INTO t_point_transactions ...
\`\`\`
**Total:** 5クエリ(変更なし)
**評価:** ✅ クエリ数増加なし
ステップ4: N+1問題の検出
新たにN+1問題が導入されていないか確認:
## N+1問題の検出
### 検証: User.wallets
**変更内容:**
\`\`\`diff
User: {
wallet: (parent, _, ctx) => {
- return prisma.t_wallets.findUnique({ where: { userId: parent.id } });
+ return ctx.loaders.wallet.load(parent.id);
}
}
\`\`\`
**評価:**
- 変更前: N+1問題あり
- 変更後: DataLoader使用、N+1問題解消 ✅
**パフォーマンス改善:**
- 100ユーザー取得時のクエリ数: 100回 → 1回
- レスポンスタイム: 5秒 → 50ms(100倍改善)
**評価:** 🟢 大幅改善
ステップ5: データベースインデックスの影響
インデックス追加によるパフォーマンス改善を確認:
## インデックスの影響
### 追加されたインデックス
\`\`\`prisma
model t_wallets {
// ...
+ @@index([expiresAt])
}
\`\`\`
---
### クエリパフォーマンス比較
#### Query: `SELECT * FROM t_wallets WHERE expiresAt < NOW()`
**変更前(インデックスなし):**
\`\`\`
Seq Scan on t_wallets (cost=0.00..25.50 rows=10 width=100)
Execution Time: 45.2 ms
\`\`\`
**変更後(インデックスあり):**
\`\`\`
Index Scan using idx_wallets_expires_at on t_wallets (cost=0.15..8.17 rows=10 width=100)
Execution Time: 2.1 ms
\`\`\`
**評価:** 🟢 大幅改善(21倍高速化)
ステップ6: メモリ使用量の比較
メモリフットプリントの変化:
## メモリ使用量
### ヒープメモリ
**変更前:**
- Used Heap: 120 MB
- Heap Limit: 512 MB
- Usage: 23%
**変更後:**
- Used Heap: 125 MB (+4.2%)
- Heap Limit: 512 MB
- Usage: 24%
**評価:** 🟢 許容範囲内(+5%以下)
---
### オブジェクト数
**変更前:**
- Total Objects: 150,000
**変更後:**
- Total Objects: 152,000 (+1.3%)
**評価:** 🟢 微増(問題なし)
ステップ7: リグレッション判定
総合的なパフォーマンス評価:
## リグレッション判定
### 判定基準
| メトリクス | 閾値 | 変更前 | 変更後 | 差分 | 判定 |
|-----------|------|--------|--------|------|------|
| Avg Response Time | +10% | 5.2ms | 5.5ms | +5.8% | ✅ Pass |
| P95 Response Time | +15% | 8.5ms | 9.0ms | +5.9% | ✅ Pass |
| P99 Response Time | +20% | 12.3ms | 13.1ms | +6.5% | ✅ Pass |
| Query Count | +0 | 5 | 5 | 0 | ✅ Pass |
| Memory Usage | +10% | 120MB | 125MB | +4.2% | ✅ Pass |
| Error Rate | +0% | 0% | 0% | 0% | ✅ Pass |
---
### 総合評価
**スコア:** 95 / 100 🟢 Excellent
**判定:** ✅ **パフォーマンスリグレッションなし**
**コメント:**
- 軽微な劣化はあるが、全て許容範囲内
- 有効期限チェックの追加によるオーバーヘッドは予想通り
- インデックス追加により一部クエリは大幅改善
- N+1問題の解消により全体的なパフォーマンス向上
**推奨アクション:**
- マージ可能
- 本番環境での監視継続
ステップ8: パフォーマンス改善の提案
さらなる最適化の提案:
## パフォーマンス改善提案
### 提案1: キャッシュ導入
**現状:**
- 有効期限チェックを毎回実行
**提案:**
\`\`\`typescript
// Redis キャッシュ(TTL: 60秒)
const cacheKey = \`wallet:expiration:\${walletId}\`;
const cached = await redis.get(cacheKey);
if (cached) return JSON.parse(cached);
const wallet = await this.repo.findById(ctx, walletId, tx);
await redis.setex(cacheKey, 60, JSON.stringify(wallet));
return wallet;
\`\`\`
**効果:**
- レスポンスタイム: 5.5ms → 0.5ms(11倍改善)
- データベース負荷: 90%削減
---
### 提案2: SELECT句の最適化
**現状:**
\`\`\`typescript
return tx.t_wallets.findUnique({ where: { id } });
\`\`\`
**提案:**
\`\`\`typescript
return tx.t_wallets.findUnique({
where: { id },
select: {
id: true,
balance: true,
expiresAt: true,
// 必要なフィールドのみ
}
});
\`\`\`
**効果:**
- データ転送量: 80%削減
- メモリ使用量: 削減
ステップ9: 比較レポート生成
# パフォーマンス比較レポート
**PR:** #123
**ブランチ:** feature/point-expiration
**比較:** main vs feature/point-expiration
**実施日:** 2026-01-15
---
## エグゼクティブサマリー
### 総合評価
**判定:** ✅ **マージ可能**
**スコア:** 95 / 100
**リグレッション:** なし(軽微な劣化は許容範囲内)
---
## 詳細比較
### レスポンスタイム
| エンドポイント | 変更前 | 変更後 | 差分 | 判定 |
|---------------|--------|--------|------|------|
| wallet(id) | 5.2ms | 5.5ms | +5.8% | ✅ |
| walletCreate | 21ms | 23ms | +9.5% | ✅ |
| pointTransfer | 45ms | 46ms | +2.2% | ✅ |
---
### クエリ数
| エンドポイント | 変更前 | 変更後 | 差分 | 判定 |
|---------------|--------|--------|------|------|
| wallet(id) | 1 | 1 | 0 | ✅ |
| pointTransfer | 5 | 5 | 0 | ✅ |
---
### パフォーマンス改善
- **N+1問題解消:** User.wallets(100倍改善)
- **インデックス追加:** expiresAt クエリ(21倍改善)
---
## 推奨アクション
### 即座に実施
- ✅ PR をマージ可能
- 🔔 本番環境で監視継続(24時間)
### 将来的に検討
- キャッシュ導入(さらなる最適化)
- SELECT句の最適化
---
## 承認
- [ ] テックリード
- [ ] DevOpsリード
活用例
例1: PRのパフォーマンス比較
/performance-diff --pr 123
出力:
- 変更前後の比較
- リグレッション判定
- マージ可否の判断
例2: リリース前の検証
/performance-diff --before v1.0.0 --after main
出力:
- バージョン間の比較
- パフォーマンス推移
参考資料
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?