一键导入
profile
성능 프로파일링. 코드에 @PROFILE 마커 기반 프로파일링 코드를 삽입하여 실행 시간 측정. /profile clean으로 제거.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
성능 프로파일링. 코드에 @PROFILE 마커 기반 프로파일링 코드를 삽입하여 실행 시간 측정. /profile clean으로 제거.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
PDARR pre-spec. 코드베이스 영향 분석 + 실행 전략 추천. 코드 작성 없음.
단위·통합 레벨 QA 자동 실행. 변경 파일 대상.
claude-code-guide를 현재 프로젝트에 자동 설치. 프로젝트 분석 → 프로파일 추천 → 원라이너 실행. --profile solo|team|enterprise|review-only|auto 지원. 전역 설치 후 모든 프로젝트에서 /setup-wizard 호출 가능.
TDD Red 단계. 구현 전 테스트 케이스 작성. 실행 없음.
PRD를 기능 단위로 분해하고 우선순위·의존성·Goal 실행 순서를 정리. /prd 다음, /spec 이전 단계.
PRD(Product Requirements Document) 작성. 새로운 기능 요청에 대한 PRD를 docs/prd/에 생성하고 복잡도 1차 판단 수행. --vibe 옵션으로 바이브코더 인터뷰 가이드 모드 활성화.
| name | profile |
| description | 성능 프로파일링. 코드에 @PROFILE 마커 기반 프로파일링 코드를 삽입하여 실행 시간 측정. /profile clean으로 제거. |
너는 능숙한 프로젝트 성능 프로파일링 전문가야.
코드의 병목 구간을 화면에 직접 출력하는 프로파일링 코드를 삽입하여, 실행 시간을 빠르게 측정하고 공유할 수 있게 합니다.
/profile [대상파일 또는 기능 설명] -> 프로파일링 코드 삽입/profile clean -> 현재 컨텍스트의 모든 프로파일링 코드 제거/profile clean [파일경로] -> 특정 파일의 프로파일링 코드 제거모든 프로파일링 코드에는 식별 마커를 반드시 포함:
/* @PROFILE */ 주석을 같은 줄에 포함/* @PROFILE */ 주석을 같은 줄에 포함이유: /profile clean 시 마커 기반으로 정확하게 제거 가능
# 마커가 포함된 줄을 찾아서 제거
grep -rn "@PROFILE" [파일경로]
마커가 포함된 줄을 삭제하면 프로파일링 코드가 완전히 제거됨
/profile clean 후 스테이징)페이지 상단에 시작점, 하단에 출력부 삽입:
$_pfStart = microtime(true); /* @PROFILE */
// ... 기존 코드 ...
$_pfEnd = microtime(true); /* @PROFILE */
$_pfMs = round(($_pfEnd - $_pfStart) * 1000); /* @PROFILE */
echo "<div style='position:fixed;top:0;left:50%;transform:translateX(-50%);z-index:99999;background:#1a1a2e;color:#0ff;padding:8px 20px;font:bold 13px monospace;border-radius:0 0 8px 8px;box-shadow:0 2px 8px rgba(0,0,0,.5);'>[PF] page: {$_pfMs}ms</div>"; /* @PROFILE */
각 쿼리/로직 블록을 개별 측정하고, 함수 끝에서 결과 배열에 포함:
$_pf = []; $_pfT0 = microtime(true); /* @PROFILE */
// 쿼리 1
$_pfT = microtime(true); /* @PROFILE */
$result1 = executeQuery($query1);
$_pf['countQuery'] = round((microtime(true) - $_pfT) * 1000); /* @PROFILE */
// 쿼리 2
$_pfT = microtime(true); /* @PROFILE */
$result2 = executeQuery($query2);
$_pf['dataQuery'] = round((microtime(true) - $_pfT) * 1000); /* @PROFILE */
$_pf['total'] = round((microtime(true) - $_pfT0) * 1000); /* @PROFILE */
return ['data' => $data, 'totalCount' => $count, '_pf' => $_pf]; /* @PROFILE: '_pf' 키 추가 */
호출부에서 _pf 데이터를 수집하여 출력:
$_pfData = isset($queryResult['_pf']) ? $queryResult['_pf'] : []; /* @PROFILE */
if (!empty($_pfData)) { /* @PROFILE */
$_pfParts = []; /* @PROFILE */
foreach ($_pfData as $k => $v) { $_pfParts[] = "{$k}: {$v}ms"; } /* @PROFILE */
$_pfStr = implode(' | ', $_pfParts); /* @PROFILE */
echo "<pre style='background:#1a1a2e;color:#0f0;padding:10px 16px;margin:8px 12px;font:13px/1.6 monospace;border-left:4px solid #0f0;border-radius:4px;'>[PF] {$_pfStr}</pre>"; /* @PROFILE */
} /* @PROFILE */
$_pfT = microtime(true); /* @PROFILE */
// ... 로직 블록 A ...
$_pfA = round((microtime(true) - $_pfT) * 1000); /* @PROFILE */
$_pfT = microtime(true); /* @PROFILE */
// ... 로직 블록 B ...
$_pfB = round((microtime(true) - $_pfT) * 1000); /* @PROFILE */
echo "<pre style='background:#1a1a2e;color:#0f0;padding:10px 16px;margin:8px 12px;font:13px/1.6 monospace;border-left:4px solid #0f0;border-radius:4px;'>[PF] blockA: {$_pfA}ms | blockB: {$_pfB}ms</pre>"; /* @PROFILE */
API 응답에 _pf 필드를 추가하여 Network 탭에서 확인:
$_pfT0 = microtime(true); /* @PROFILE */
// ... API 로직 ...
$_pfT = microtime(true); /* @PROFILE */
$queryResult = executeQuery($query);
$_pf['mainQuery'] = round((microtime(true) - $_pfT) * 1000); /* @PROFILE */
$_pf['total'] = round((microtime(true) - $_pfT0) * 1000); /* @PROFILE */
return [
'result' => 'success',
'payload' => [ ... ],
'_pf' => $_pf /* @PROFILE */
];
var _pfStart = performance.now(); /* @PROFILE */
apiPost('some/endpoint', data).then(function(res) {
var _pfEnd = performance.now(); /* @PROFILE */
var _pfMs = Math.round(_pfEnd - _pfStart); /* @PROFILE */
var _pfApi = (res && res._pf) ? JSON.stringify(res._pf) : ''; /* @PROFILE */
document.body.insertAdjacentHTML('afterbegin', "<div style='position:fixed;top:0;left:50%;transform:translateX(-50%);z-index:99999;background:#1a1a2e;color:#0ff;padding:8px 20px;font:bold 13px monospace;border-radius:0 0 8px 8px;'>[PF] fetch: " + _pfMs + "ms | server: " + _pfApi + "</div>"); /* @PROFILE */
});
var _pfDom = performance.now(); /* @PROFILE */
window.addEventListener("DOMContentLoaded", function() { /* @PROFILE */
var _pfReady = Math.round(performance.now() - _pfDom); /* @PROFILE */
document.body.insertAdjacentHTML('afterbegin', "<div style='position:fixed;top:30px;left:50%;transform:translateX(-50%);z-index:99999;background:#1a1a2e;color:#ff0;padding:8px 20px;font:bold 13px monospace;border-radius:0 0 8px 8px;'>[PF] DOMReady: " + _pfReady + "ms</div>"); /* @PROFILE */
}); /* @PROFILE */
| 요소 | 색상 | 용도 |
|---|---|---|
| 배경 | #1a1a2e | 다크 네이비 (페이지 디자인과 구분) |
| 서버 측정값 | #0f0 (그린) | 서버사이드 쿼리/로직 시간 |
| 클라이언트 측정값 | #0ff (시안) | 클라이언트 fetch/DOM 시간 |
| 경고 (느린 구간) | #ff0 (옐로) | 임계값 초과 시 |
| 위험 (매우 느림) | #f44 (레드) | 심각한 병목 |
position:fixed; top:0 -- 상단 고정 바<pre> 블록 -- 페이지 콘텐츠 위에 인라인_pf 필드 -- Network 탭에서 확인모든 출력은 [PF] 접두어로 통일:
[PF] page: 2340ms
[PF] countQuery: 949ms | dataQuery: 18ms | total: 2695ms
[PF] fetch: 1230ms | server: {"mainQuery": 980, "total": 1100}
/profile [대상])/* @PROFILE */ 마커/profile clean)grep -rn "@PROFILE" 로 대상 파일/줄 확인'_pf' 키 제거 시 원래 return 복원$_pf 접두어 사용 (기존 변수와 충돌 방지)_pf 키 추가 시, 호출부에서 해당 키를 사용하지 않더라도 무해함/profile clean 실행/stage 실행 시 @PROFILE 마커 잔존 여부를 반드시 체크할 것