-
Notifications
You must be signed in to change notification settings - Fork 0
⚡ Bolt: R 데이터 프레임 단일 벡터 할당 최적화 #285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -598,15 +598,17 @@ autoFIPC <- | |
| # Preserve mirt's structural estimability flags. Forcing every row TRUE | ||
| # frees boundary parameters such as 2PL g/u and makes the Hessian unstable. | ||
|
|
||
| NewScaleParms[NewScaleParms$item == 'GROUP', "est"] <- FALSE | ||
| OldScaleParms[OldScaleParms$item == 'GROUP', "est"] <- FALSE | ||
| # ⚡ Bolt: Use direct vector subsetting (e.g. df$col[idx] <- val) instead of 2D data frame assignment (e.g. df[idx, 'col'] <- val) | ||
| # to bypass method dispatch overhead and significantly improve memory copy performance. | ||
| NewScaleParms$est[NewScaleParms$item == 'GROUP'] <- FALSE | ||
| OldScaleParms$est[OldScaleParms$item == 'GROUP'] <- FALSE | ||
|
|
||
| NewScaleParms[NewScaleParms$name == "COV_11", "est"] <- TRUE | ||
| OldScaleParms[OldScaleParms$name == "COV_11", "est"] <- TRUE | ||
| NewScaleParms$est[NewScaleParms$name == "COV_11"] <- TRUE | ||
| OldScaleParms$est[OldScaleParms$name == "COV_11"] <- TRUE | ||
|
|
||
| if (itemtype == 'Rasch') { | ||
| NewScaleParms[NewScaleParms$name == "a1", "est"] <- FALSE | ||
| OldScaleParms[OldScaleParms$name == "a1", "est"] <- FALSE | ||
| NewScaleParms$est[NewScaleParms$name == "a1"] <- FALSE | ||
| OldScaleParms$est[OldScaleParms$name == "a1"] <- FALSE | ||
|
Comment on lines
+603
to
+611
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📝 Info: Vector assignment preserves prior behavior The conversions at R/aFIPC.R:603-611 and R/aFIPC.R:881-882 are behavior-preserving: Was this helpful? React with 👍 or 👎 to provide feedback. |
||
| } | ||
|
|
||
| #IPD | ||
|
|
@@ -875,8 +877,9 @@ autoFIPC <- | |
| 'MEAN = F1' | ||
| )) | ||
|
|
||
| NewScaleParms[NewScaleParms$name == "MEAN_1", "est"] <- TRUE | ||
| OldScaleParms[OldScaleParms$name == "MEAN_1", "est"] <- TRUE | ||
| # ⚡ Bolt: Direct vector subsetting to avoid slow [<-.data.frame dispatch overhead | ||
| NewScaleParms$est[NewScaleParms$name == "MEAN_1"] <- TRUE | ||
| OldScaleParms$est[OldScaleParms$name == "MEAN_1"] <- TRUE | ||
| } else { | ||
| LinkedModelSyntax <- | ||
| mirt::mirt.model(paste0( | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: ContextualWisdomLab/aFIPC
Length of output: 4350
🌐 Web query:
R language semantics df$col[index] <- value data.frame replacement dispatch [<-.data.frame $<-.data.frame copy complexity💡 Result:
In R, the expression df$col[index] <- value involves a composition of two separate S3 dispatch operations: first the extraction/replacement of the column via $<-.data.frame, and then the replacement of elements within that column via [.data.frame (or [<-.data.frame for the column vector itself) [1][2]. Dispatch Mechanism: The $ operator does not have a specific data.frame method; instead, R uses the default list-like dispatch for$, which treats the data frame as a list [1][3]. However, for assignment, $ <-.data.frame is specifically defined to handle data frame structures, ensuring row counts are respected and values are replicated/coerced as needed [1][4]. When you execute df$col[index] <- value, R effectively performs a two-step process: 1. It accesses or creates the column using $<-.data.frame (or sometimes $ for extraction if interpreted as a multi-step expression) [1][3]. 2. It calls the appropriate subassignment method (e.g., [<-) on the resulting vector [2]. Copy Complexity and Performance: R’s copy-on-modify semantics mean that modifying a data frame often triggers memory duplication [5]. The complexity is notably high because: - Temporary Objects: R often creates an internal temporary copy (e.g., tmp) of the data frame before calling the replacement function to protect the original object during the operation [6][7]. - Function Overhead: Since many of these replacement methods are standard R functions rather than primitives, they increment the reference count of the object, which can force unnecessary deep copies if the object is shared [5][7]. - Column-wise Modification: Modifying a single column typically requires a copy of that column, but if the operation is interpreted as modifying the data frame structure (e.g., adding a row), the overhead increases as the entire data frame may be duplicated [5]. Because R's internal reference counting (which tracks 0, 1, or "many" references) can be conservative, it often triggers copies even when a developer might intend an in-place modification [5]. Empirical testing with tracemem is the standard way to diagnose these copies, as predicting them theoretically is challenging due to these complex, version-dependent optimization rules [5].
Citations:
복잡도와 디스패치 설명을 수정하세요.
df$col[df$idx == 'val'] <- new_val도 조건식과 인덱스 처리에O(n)비용이 들며, 대입 과정에서$<-.data.frame디스패치가 발생할 수 있습니다. 따라서 “O(1)에 가까운” 표현과 디스패치 오버헤드 감소를 단정하지 말고, 대표 입력과 R 버전별 벤치마크 결과로 성능 차이를 설명하세요.🤖 Prompt for AI Agents