From 103ca39fdbe12c098c232fe39592d1901154ed47 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Thu, 27 Aug 2026 03:57:55 +0000 Subject: [PATCH] Replace sapply with vapply for performance and safety Replaced sapply(mispatts, nrow) with vapply(mispatts, nrow, numeric(1)) in llcont.lavaan to reduce type inference and simplification overhead during missing data pattern evaluation. --- .jules/bolt.md | 3 +++ R/llcont.R | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index f658475..adb4be5 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -15,3 +15,6 @@ ## 2024-05-15 - [R Performance: ifelse Overhead] **Learning:** In R, ifelse evaluates both true and false branches entirely before subsetting, which is very inefficient for vector operations. **Action:** Optimize this by preallocating with res <- Y * 0 to preserve attributes and using vectorized subsetting like if any cond res subset <- ... +## 2024-05-14 - R Type Inference Overhead +**Learning:** `sapply()` over lists in R incurs significant overhead because it must deduce and attempt to simplify the return type dynamically. +**Action:** Always prefer `vapply()` with a predefined return type template (e.g., `numeric(1)`) over `sapply()` when operating on lists where the expected output length and type are known in advance. This improves both execution speed and type safety. diff --git a/R/llcont.R b/R/llcont.R index d8e496a..b74269b 100644 --- a/R/llcont.R +++ b/R/llcont.R @@ -407,7 +407,7 @@ llcont.lavaan <- function(x, ...){ if(tolower(lavInspect(x, "options")$missing) == "ml.x") stop("cannot handle lavaan models with missing='ml.x'. consider using missing='ml'.", call. = FALSE) mispatts <- lavInspect(x, "patterns") if(any(class(mispatts) == "list")){ - npatts <- max(sapply(mispatts, nrow)) + npatts <- max(vapply(mispatts, nrow, numeric(1))) } else { npatts <- nrow(mispatts) }