diff --git a/.jules/bolt.md b/.jules/bolt.md index 22d58d2..b118e90 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -5,3 +5,7 @@ ## 2024-05-18 - R 언어에서 루프 내 정규식 탐색 병목 최적화 **Learning:** R에서 데이터 프레임의 크기가 커질수록 루프 내에서 컬럼명을 추출하고 정규식을 이용해(`grep`) 문자열을 탐색하는 작업이 상당한 성능 오버헤드를 발생시킨다. 특히 O(N) 탐색을 루프 안에서 반복할 경우 O(N^2)의 비효율성을 초래한다. **Action:** 루프 내부에서 자주 호출되는 컬럼명이나 데이터 프레임 구조 탐색을 루프 밖으로 빼서 한 번만 계산하여 벡터로 저장하도록 한다. 정규식보다는 완전 일치 탐색(`%in%`, `match`)이 가능하도록 벡터 연산을 활용해 O(1) 수준으로 성능을 끌어올려야 한다. + +## 2026-06-30 - Avoid factor allocation for response-category counts +**Learning:** `levels(as.factor(x))` allocates a factor just to count response categories, which is unnecessary in repeated common-item loops. +**Action:** Use `length(na.omit(unique(x)))` for category-count comparisons while preserving the existing exact item-name matching. diff --git a/R/aFIPC.R b/R/aFIPC.R index e57c907..d0329f2 100644 --- a/R/aFIPC.R +++ b/R/aFIPC.R @@ -720,12 +720,8 @@ autoFIPC <- if ( !is.na(newFormItemName) && !is.na(oldFormItemName) && - (length(levels(as.factor( - newFormModel@Data$data[, newFormItemName] - ))) == - length(levels(as.factor( - oldFormModel@Data$data[, oldFormItemName] - )))) + (length(na.omit(unique(newFormModel@Data$data[, newFormItemName]))) == + length(na.omit(unique(oldFormModel@Data$data[, oldFormItemName])))) ) { message( 'applying ',