Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@
## 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 <- ...
## 2026-08-11 - Vectorized subsetting over ifelse()

**Learning:** In R, `ifelse()` evaluates both true and false branches entirely before subsetting, causing significant overhead for expensive operations. Replacing it with vectorized subsetting (and properly handling NA conditions) can yield ~56-70% performance improvements.
**Action:** Replace `ifelse()` with vectorized subsetting (e.g., `cond <- m <= 0; cond[is.na(cond)] <- FALSE; res[cond] <- 0`) when optimizing high-traffic code paths.
2 changes: 2 additions & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ Package: nonnest2
Title: Tests of Non-Nested Models
Version: 0.5-9
Date: 2026-03-31
Author: Edgar Merkle [aut, cre], Dongjun You [aut], Lennart Schneider [ctb], Mauricio Garnier-Villarreal [ctb], Seongho Bae [ctb], Phil Chalmers [ctb]
Maintainer: Edgar Merkle <merklee@missouri.edu>
Authors@R: c(person(given = "Edgar", family = "Merkle",
role = c("aut","cre"), email = "merklee@missouri.edu"),
person(given = "Dongjun", family = "You", role = "aut"),
Expand Down
14 changes: 12 additions & 2 deletions R/llcont.R
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,22 @@ llcont.glm <- function(x, ...){
if(is.matrix(y)) {
## Bolt: replaced apply(..., 1, sum) with optimized rowSums() for performance
n <- rowSums(y)
y <- ifelse(n == 0, 0, y[, 1]/n)
## Bolt: replaced ifelse with vectorized subsetting for performance
y_tmp <- y[, 1] / n
cond <- n == 0
cond[is.na(cond)] <- FALSE
y_tmp[cond] <- 0
Comment on lines +59 to +60

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ“ Info: Missing masks preserve valid results

A missing cond leaves the division result missing, while zero denominators are overwritten. Only unsupported NaN inputs can retain NaN instead of NA.

Devin Review

Was this helpful? React with πŸ‘ or πŸ‘Ž to provide feedback.

y <- y_tmp
} else {
n <- rep.int(1, length(y))
}
m <- if (any(n > 1)) n else wt
wt <- ifelse(m > 0, (wt/m), 0)
## Bolt: replaced ifelse with vectorized subsetting for performance
wt_tmp <- wt / m
cond <- m <= 0
cond[is.na(cond)] <- FALSE
wt_tmp[cond] <- 0
wt <- wt_tmp
dbinom(round(m * y), round(m), mpreds, log = TRUE) * wt
},
quasibinomial = {
Expand Down
Loading