OpenClaw 성능
낭비(Waste) 는 요청에 필요하지 않은 작업입니다. 큰 속도 향상은 동일한 작업을 더 빠르게 수행하는 것이 아니라 낭비를 삭제함으로써 얻어집니다. 캐시는 최후의 수단입니다: 캐시는 키, 무효화 또는 적중률이 깨질 때까지 낭비를 숨기고, 낭비는 다시 돌아옵니다.
1. 측정
첫 번째 실행 전에 PR에 승인 규칙을 작성하세요: 흐름, 작업 부하, 메트릭, 콜드/웜, 샘플 수, 그리고 승리 또는 회귀로 간주되는 변경.
| 흐름 | 커밋된 작업 부하 |
|---|---|
| CLI 시작 | pnpm test:startup:bench (:check는 예산을 보유) |
| 게이트웨이 시작 / 재시작 | scripts/bench-gateway-startup.ts, scripts/bench-gateway-restart.ts, scripts/perf/post-restart-burst-measure.ts |
| 채팅 턴, 턴당 프레임 | scripts/bench-channel-turn.mts, scripts/perf/transcript-broadcast-measure.ts |
| 컨트롤 UI 콜드 로드 | scripts/bench-control-ui-cold-load.ts, pnpm ui:check-performance (:base 비교) |
| 세션 목록, 멀티 에이전트 형태 | scripts/perf/team-shape-fixture.ts, src/gateway/session-list-viewers.perf.test.ts |
| 동시성, SQLite 상태 | scripts/bench-gateway-concurrency.ts, pnpm test:sqlite:perf |
- 먼저 횟수를 세기: 벽시계 시간 전에 작업당 연산 횟수(SQL 문, RPC 및 프레임, 파일 읽기, 카탈로그 또는 레지스트리 로드, 스폰, 렌더링). 횟수는 부하가 걸린 호스트에서도 일정하게 유지됩니다. 0이어야 하는 횟수는 버그입니다.
- 실제 흐름: 테스트 중인 헤드의 격리된 게이트웨이, 실제 전송, 느린 경로 포함. 모의 게이트웨이, 오래된 빌드 또는 개발 서버는 다른 것을 측정합니다.
- 샘플: 기준선과 후보를 교대로 실행(ABAB), 각각 최소 5회, 콜드와 웜을 분리; 중앙값과 p95를 분산과 함께, 직렬로 실행, 호스트 부하 기록.
- 재실행 가능: 커밋된 스크립트만 인정됨; 적합한 것이 없으면 기존 스크립트를 확장하세요.
- 프로파일링:
node --cpu-prof스레드별, 또는 브라우저 성능 추적, 핫 경로에서.
흐름에 커밋된 작업 부하, 기준선 테이블 및 작성된 규칙이 있을 때 완료됩니다.
2. 낭비 찾기
계산된 모든 연산에 대해 질문하세요: 이 요청에 이것이 필요한가? 반복되는 OpenClaw 낭비:
- 임계 경로에서의 조기 작업: 플러그인 로더를 가져온 레지스트리 조회(#133518, 47.07초 → 10.36초); 시작 시 선택적 런타임 로드(#119374).
- 행당 또는 호출당 재계산: 보관된 행당 동기 읽기(#156665, 56,700회 읽기 → 0); 프레임당 해결된 로그 패턴(#150042, 10,000개 프레임당 539 → 17ms).
- 승인된 상태 재확인: 웜 핸들에 대한 스키마, 승인 또는 신선도 검사(#166102, #172676; SQLite 승인 체인의 14개 PR).
- 스트리밍된 델타당 전체 재스캔: 모든 토큰이 전체 응답을 재처리(#158526, 256KiB에서 5,342 → 1ms CPU).
- 자신의 쓰기 다시 읽기: 조회당 두 번의 데이터베이스 백업(#161551, 772.8 → 7.7ms); Doctor가 방금 확인한 것을 다시 스캔하고 백업(#174665, ~26 → 3.0초).
- 반복된 카탈로그 또는 레지스트리 빌드: 시작 시 에이전트당 카탈로그 재빌드(#116261, 24.9 → 5.0초); 미스 또는 TTL당 재빌드(#127178, #167008).
- 선택적 데이터 대기: 사용량 페이지가 공급자 플랜을 기다리고 관련 없는 읽기를 재시도(#176358).
- 방어적 복사 및 래핑: 턴당
structuredClone(#172940, 1.685MiB → 0); 값당 경계 래핑(#163818, 이벤트당 11,571 → 500ns). - 호출당 스폰 또는 팬아웃: 해결당 자식 프로세스(#155779, 100 → 0).
- 렌더링 캐스케이드 및 전체 페이로드: 업데이트당 렌더(#159400, 250 → 79); 하나의 델타에 대해 전체 행 재전송(#165404, 21.75 → 0.95MB).
각 지배적인 횟수가 그것을 발행하는 코드로 추적되고, "필요함"에 대한 예/아니오가 있을 때 완료됩니다.
3. 이 순서로 수정하세요
- 낭비를 삭제하세요. 삭제는 거의 되돌아오지 않습니다; 실패한 삭제는 가드를 제거했으므로, 계약을 보호하는 모든 검사를 유지하고 계약이 여전히 유효함을 증명하세요.
- 소유자에게 한 번: 호출자는 소유자가 기록한 사실을 소비합니다.
- 준비된 사실을 핫 경로를 통해 전달하세요.
- 독립적인 작업을 배치로 묶고, 배치가 프레임, 지연 시간 꼬리 및 콜드 스타트를 안정적으로 유지함을 증명하세요: 병합(coalescing)은 세 번 되돌려졌습니다(#162560, #173901, #175092).
- 캐시하세요, 단 1-4단계가 적용되지 않는 이유를 문서화하세요. "캐시 정체성"을 따르고, 소유자의 쓰기에서 무효화하며, 크기를 제한하고, 교대 작업 횟수 테스트를 추가하세요. 네 개의 캐시 재수정 중 세 개는 조용한 미스였습니다: 읽는 사람이 서로를 제거(#115369 → #174741), 예산이 쓰레싱(#149773 → #149879).
워커 이동 또는 지연은 비용을 재배치합니다; 메인 스레드와 총 작업을 모두 세세요.
횟수에서 낭비가 사라졌거나, PR이 어떤 단계에서 중단되었는지와 그 이유를 명시했을 때 완료됩니다.
4. 배포
- 동일한 규칙 하에 기준선과 후보에 대해 1단계 작업 부하를 재실행하세요.
- 모든 사용자 관련 메트릭이 유지되거나 개선됨: 지연 시간, p95/p99, 프레임, 콜드 스타트, CPU, 메모리, 횟수. 더 나빠진 메트릭은 PR에서 소유자의 명시적 동의가 필요합니다. 하나의 셀에서 20% 움직임은 중지 신호이며, "분산 범위 내"가 아닙니다: 되돌려진 6개의 성능 PR 중 5개는 자체 본문에서 회귀를 보여주었습니다.
- 측정 가능한 이득이 없는 변경은 되돌리세요.
- 증거는 PR에 있습니다. 새로운 테스트가 아닙니다: 전/후 횟수가 증거입니다. 이 낭비가 이전에 다시 발생한 경우에만 흐름의 기존 작업 횟수 테스트를 확장하세요; test-audit이 테스트 가치를 소유합니다.
- PR 증거: 작업 부하 명령어, 승인 규칙, 전/후 테이블(횟수와 시간, 중앙값 및 p95, 샘플 수), 제거된 낭비, 그리고 잘못된 방향으로 움직인 모든 메트릭.
테이블이 1단계에서 작성된 규칙을 충족할 때 완료됩니다.
관련 항목
테스트 스위트 속도: openclaw-test-performance. 테스트 힙 증가: openclaw-test-heap-leaks. CI 용량: openclaw-ci-limits.