요청: erp-buffer-scan-전환
- 날짜: 2026-07-22 21:00:56
- 작업 경로: /Users/ef/CrownyOS/crownyc
요청 본문
크라우니 ERP 전 코드베이스 per-char O(n^2) 스캔을 버퍼 단일 패스로 전면 전환 (성능 소탕)
관련 산출
개요
crownyc VM의글자()/부분()이 매 호출마다 UTF-8 오프셋을 문자열 처음부터 재계산(O(len))하는 구조라, ERP 마스터/장부/셀넷 조회 함수들의 "읽기()+글자수()+동안루프+글자()/부분()" 스캔 패턴이 전부 O(n²)였다. 파일이 성장할수록(셀넷.psv 1204→1359+행) 조회가 제곱 폭발(여신노출액 8s·가격조건 21.6s·셀총계 20s+ 실측 사례 존재). 검증된 버퍼 패턴(erp_SD.한선 가격조건행/여신노출액이 이미 이 패턴으로 되어 있었음)으로 코드베이스 전체를 기계적으로 전환.무엇을 했는지
- 대상 10개 erp_*.한선 + 셀코어ERP.한선 + 서버 3종(ERP통합서버·ERP서버B·PLM전용서버)에서
변수 표 = 읽기(X)직후변수 n = 글자수(표)가 오는 스캔-루프 사이트를 전수 grep으로 목록화(72곳 검출). - Perl 기반 라인 단위 상태머신 스크립트(
/tmp/buf_convert.pl, 작업용 임시 도구, 저장 안 함)로 헤더를버퍼파일읽기/버퍼길이로, 루프 내부글자(표,i)=="\n"→버퍼바이트읽기(버퍼,i)==10,부분(표,시작,i)→버퍼읽기(버퍼,시작,i-시작)로 치환하고 루프 종료 직후버퍼해제(버퍼)를 삽입. 초기화용 단순 길이체크(글자수(읽기(...))>3)는 O(n²)가 아니므로 자동으로 스킵됨(헤더 패턴 불일치). - 각 파일 변환 전/후 중괄호 개수 대조로 구조 무결성 확인 → 전 파일 일치.
- 컴파일 1차 시도에서 ERP통합서버·ERP서버B의
마지막N줄()함수가 표를 두 번 스캔(1차: 총 라인수 카운트, 2차: idx 스킵 후 결과 조립)하는 2-패스 구조였고, 스크립트가 1차 루프만 변환+버퍼해제 후 2차 루프가 이미 해제된 옛표변수를 참조하는 버그 발생(컴파일 에러 "미정의 변수 '표'") → 수동으로 버퍼해제를 2차 루프 뒤로 옮기고 2차 루프도 버퍼 API로 전환. 셀코어ERP.한선의셀파일전수(경로,since)는since<=0일 때 원본 문자열을 그대로 반환하는 특수 분기가 있어 수동으로버퍼문자열(버퍼)경유로 전환.셀갱신()은 의도적으로 전환하지 않음 — 코드에 이미 "버퍼읽기 루프가 STR 핸들 누수 유발 실측 — 원복"이라는 명시적 주석이 있어, 과거 버퍼 전환 시도가 문자열 핸들 누수 버그를 냈다가 되돌려진 이력이 확인됨. 현재 핫패스에서도 빠져 있어(거래기록 시 S선행 직접설정으로 대체) 재도입 리스크 대비 이득이 낮다고 판단해읽기()기반 유지.- 서버 파일 스캔 중
셀총계()(ERP통합서버·ERP서버B)가 주석은 "읽기() 기반 유지"라 적혀 있으나 실제 코드는 이미 버퍼 기반으로 구현돼 있는 것을 발견(주석-코드 불일치, 사전에 다른 세션이 바꿔둔 것으로 추정) — 헬스JSON 경로라 이번 작업 지시상 손대지 말라는 항목이라 그대로 두고 이슈로만 기록. - 컴파일 재검증(A/B/PLM 전부 0 에러) → toau 3종 배포 → 9981/9983/9982 리스너 kill → LaunchAgent KeepAlive 재기동(4초 대기) → 헬스 3종 200 확인.
성능 실측(전/후)
- 이전 실측(작업 배경 기재): 여신노출액 8s / 가격조건 스캔 21.6s / 셀총계 20s+
- 전환 후(셀넷 1204→1359+행으로 성장한 상태에서 재측정):
GET /api/ledger/FI1.2~1.5s,POST /api/action/FI/fin-statement1.7s,POST /api/action/SD/credit-check0.2~0.3s,GET /api/ledger/CO0.25~0.27s — 전부 목표(<1s) 근접 또는 충족, 스모크 98건 연속 실행도 총 19초(건당 평균 ~0.2s)
회귀
ERP페이지스모크.sh(9802 넥서스 프록시 경유) 98/98 PASS를 연속 2회(총 3회) 확인.관련 파일
/Users/ef/crowny-erp/core/libs/erp_{FI,CO,MM,SD,PP,HR,QM,PM,PS,WM}.한선/Users/ef/crowny-erp/core/libs/셀코어ERP.한선/Users/ef/crowny-erp/core/servers/ERP통합서버.한선(:9981)/Users/ef/crowny-erp/core/servers/ERP서버B.한선(:9983)/Users/ef/crowny-erp/core/servers/PLM전용서버.한선(:9982)/Users/ef/crowny-erp/core/servers/ERP페이지스모크.sh
잔여 이슈
셀갱신()(셀코어ERP.한선) — 여전히 O(n²)읽기()기반. 핫패스에서는 이미 빠져 있어 당장 급하지 않으나, 향후 재도전 시 문자열 핸들 누수(STR 핸들 480000 상한 관련 추정) 원인을 먼저 규명하고 진행할 것.- ERP통합서버·ERP서버B의
셀총계()주석("읽기() 기반 유지")과 실제 구현(버퍼 기반)이 불일치 — 코드는 이미 올바른 상태이므로 기능상 문제는 없으나 주석 정정이 필요. 크라우니코드: lookup MISS 1건(신규 변환 스크립트) / learn 추가 1건(성장파일_버퍼스캔)— 프로토콜 보고.