From 85684b27ea26f9465e6c5f93df0443de6b4618e8 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 5 Sep 2026 16:16:32 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Replace=20O(N)=20memory?= =?UTF-8?q?=20allocation=20with=20O(1)=20attribute=20access?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .jules/bolt.md | 3 +++ R/aFIPC.R | 10 ++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index 7d3c603f..31a6f6c8 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -16,3 +16,6 @@ ## 2025-02-12 - R 언어에서 반복적인 mirt 모델 생성 시 불필요한 데이터프레임 부분집합 추출 최적화 **Learning:** R에서 데이터프레임의 특정 열을 추출하는 작업(`df[cols]`)은 O(N)의 메모리 복사를 수반합니다. `autoFIPC`에서 `mirt` 모델의 파라미터를 설정하거나 호출하는 과정 중에 `newformXDataK[colnames(newFormModel@Data$data)]` 코드가 반복해서 사용되었고, 심지어 `ncol()`을 위해 단순히 개수를 구할 때도 사용되어 불필요한 메모리 할당과 오버헤드를 초래했습니다. **Action:** 조건문이나 반복문 내부에서 불필요하게 데이터프레임 부분집합 연산이 반복되지 않도록 외부에서 한 번만 `linkedFormData <- newformXDataK[colnames(newFormModel@Data$data)]`로 캐싱(caching)한 뒤, `ncol(linkedFormData)`와 `data = linkedFormData` 형태로 재사용하여 메모리 복사와 O(N) 오버헤드를 방지해야 합니다. +## 2024-07-13 - R 언어에서 불필요한 서브셋팅 복사를 제거한 컬럼명 접근 O(1) 최적화 +**Learning:** 데이터프레임에서 이미 알고 있는 컬럼명 리스트 `cols`를 이용해 `colnames(df[cols])`를 호출하면, 불필요하게 `df`를 부분 복사(copy)하게 되어 메모리 오버헤드와 O(N)의 성능 저하가 발생합니다. +**Action:** 컬럼명 배열만 필요한 경우, 데이터를 복사하지 않고 기존의 `cols` 벡터를 직접 재사용하여(`cols` 혹은 `intersect(colnames(df), cols)`) O(1) 수준으로 성능을 최적화하고 메모리 낭비를 방지해야 합니다. diff --git a/R/aFIPC.R b/R/aFIPC.R index 62546519..07e90b4f 100644 --- a/R/aFIPC.R +++ b/R/aFIPC.R @@ -619,9 +619,10 @@ autoFIPC <- )) IPDItemCount <- 0 + # ⚡ Bolt: Avoid O(N) memory copy by extracting colnames directly instead of subsetting dataframe # IPD target item checking - newFormColNames <- colnames(newformXDataK[colnames(newFormModel@Data$data)]) - oldFormColNames <- colnames(oldformYDataK[colnames(oldFormModel@Data$data)]) + newFormColNames <- colnames(newFormModel@Data$data) + oldFormColNames <- colnames(oldFormModel@Data$data) # ⚡ Bolt: Vectorized match() to avoid dynamic array growth overhead inside a for loop idxNew <- match(newformCommonItemNames, newFormColNames) @@ -749,8 +750,9 @@ autoFIPC <- } } - newFormColNames <- colnames(newformXDataK[colnames(newFormModel@Data$data)]) - oldFormColNames <- colnames(oldformYDataK[colnames(oldFormModel@Data$data)]) + # ⚡ Bolt: Avoid O(N) memory copy by extracting colnames directly instead of subsetting dataframe + newFormColNames <- colnames(newFormModel@Data$data) + oldFormColNames <- colnames(oldFormModel@Data$data) # ⚡ Bolt: Cache parameter indices to avoid O(N) linear search inside loop newScaleParmsItemIdxCache <- split(seq_len(nrow(NewScaleParms)), NewScaleParms$item) From 3839c9615c3bb43eeb3d97d2f34825de59f73a1c Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sun, 6 Sep 2026 09:47:42 +0900 Subject: [PATCH 2/2] chore: keep Bolt guidance scoped to protected baseline --- .jules/bolt.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index 31a6f6c8..7d3c603f 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -16,6 +16,3 @@ ## 2025-02-12 - R 언어에서 반복적인 mirt 모델 생성 시 불필요한 데이터프레임 부분집합 추출 최적화 **Learning:** R에서 데이터프레임의 특정 열을 추출하는 작업(`df[cols]`)은 O(N)의 메모리 복사를 수반합니다. `autoFIPC`에서 `mirt` 모델의 파라미터를 설정하거나 호출하는 과정 중에 `newformXDataK[colnames(newFormModel@Data$data)]` 코드가 반복해서 사용되었고, 심지어 `ncol()`을 위해 단순히 개수를 구할 때도 사용되어 불필요한 메모리 할당과 오버헤드를 초래했습니다. **Action:** 조건문이나 반복문 내부에서 불필요하게 데이터프레임 부분집합 연산이 반복되지 않도록 외부에서 한 번만 `linkedFormData <- newformXDataK[colnames(newFormModel@Data$data)]`로 캐싱(caching)한 뒤, `ncol(linkedFormData)`와 `data = linkedFormData` 형태로 재사용하여 메모리 복사와 O(N) 오버헤드를 방지해야 합니다. -## 2024-07-13 - R 언어에서 불필요한 서브셋팅 복사를 제거한 컬럼명 접근 O(1) 최적화 -**Learning:** 데이터프레임에서 이미 알고 있는 컬럼명 리스트 `cols`를 이용해 `colnames(df[cols])`를 호출하면, 불필요하게 `df`를 부분 복사(copy)하게 되어 메모리 오버헤드와 O(N)의 성능 저하가 발생합니다. -**Action:** 컬럼명 배열만 필요한 경우, 데이터를 복사하지 않고 기존의 `cols` 벡터를 직접 재사용하여(`cols` 혹은 `intersect(colnames(df), cols)`) O(1) 수준으로 성능을 최적화하고 메모리 낭비를 방지해야 합니다.