From b8b0d501907dbb9254378a609e3d05c2992c245c Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Tue, 30 Jun 2026 16:37:23 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Cache=20parameter=20indices?= =?UTF-8?q?=20in=20common=20item=20loop=20to=20avoid=20redundant=20O(N)=20?= =?UTF-8?q?array=20scans?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .jules/bolt.md | 4 ++++ R/aFIPC.R | 20 ++++++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index cfa2846..e456c8f 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -21,3 +21,7 @@ ## 2026-06-30 - Preserve NA handling when removing factor conversions **Learning:** `levels(as.factor(x))` excludes missing responses from the category count, so a faster replacement must not count `NA` as an extra response category. **Action:** Keep `na.omit(unique(x))` rather than plain `unique(x)` in response-category comparisons. + +## 2026-06-30 - Cache vector-search indexes in R loops +**Learning:** Redundant `which()` array scans inside loops introduce unnecessary O(N) overhead during array subsetting, especially when accessing the exact same index multiple times within the loop body. In this codebase's common item loop, repeated `which(NewScaleParms$item == ...)` calls were a bottleneck. +**Action:** Cache the resulting index into a variable (e.g. `idx <- which(...)`) at the start of the relevant block and reuse it for all subsequent operations to avoid repeated O(N) penalty. diff --git a/R/aFIPC.R b/R/aFIPC.R index d0329f2..0423214 100644 --- a/R/aFIPC.R +++ b/R/aFIPC.R @@ -723,11 +723,15 @@ autoFIPC <- (length(na.omit(unique(newFormModel@Data$data[, newFormItemName]))) == length(na.omit(unique(oldFormModel@Data$data[, oldFormItemName])))) ) { + newItemName <- paste0(newformCommonItemNames[i]) + oldItemName <- paste0(oldformCommonItemNames[i]) + newIdx <- which(NewScaleParms$item == newItemName) + oldIdx <- which(OldScaleParms$item == oldItemName) message( 'applying ', - paste0(newformCommonItemNames[i]), + newItemName, ' <<< ', - paste0(oldformCommonItemNames[i]), + oldItemName, ' as common item use' ) @@ -735,7 +739,7 @@ autoFIPC <- ' Newform Parms: ', paste0( NewScaleParms[ - which(NewScaleParms$item == paste0(newformCommonItemNames[i])), + newIdx, "value" ], ' ' @@ -745,7 +749,7 @@ autoFIPC <- ' Oldform Parms: ', paste0( OldScaleParms[ - which(OldScaleParms$item == paste0(oldformCommonItemNames[i])), + oldIdx, "value" ], ' ' @@ -753,18 +757,18 @@ autoFIPC <- ) NewScaleParms[ - which(NewScaleParms$item == paste0(newformCommonItemNames[i])), + newIdx, "value" ] <- OldScaleParms[ - which(OldScaleParms$item == paste0(oldformCommonItemNames[i])), + oldIdx, "value" ] message( ' Linkedform Parms: ', paste0( NewScaleParms[ - which(NewScaleParms$item == paste0(newformCommonItemNames[i])), + newIdx, "value" ], ' ' @@ -773,7 +777,7 @@ autoFIPC <- ) NewScaleParms[ - which(NewScaleParms$item == paste0(newformCommonItemNames[i])), + newIdx, "est" ] <- FALSE