Skip to content

Commit e16c2be

Browse files
authored
ALTREP list performance fix: Never clone in vec_clone_referenced() when owned (#1884)
* Never clone when `owned` * NEWS bullet * Add number
1 parent 9552ebc commit e16c2be

File tree

3 files changed

+9
-11
lines changed

3 files changed

+9
-11
lines changed

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# vctrs (development version)
22

3+
* Fixed a performance issue with `vec_c()` and ALTREP vectors (in particular,
4+
the new ALTREP list vectors in R-devel) (#1884).
5+
36
* Fixed an issue with complex vector tests related to changes in R-devel
47
(#1883).
58

src/owned.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,8 @@ static inline enum vctrs_owned vec_owned(SEXP x) {
1111
}
1212

1313
// Wrapper around `r_clone_referenced()` that only attempts to clone if
14-
// we indicate that we don't own `x`, or if `x` is ALTREP.
15-
// If `x` is ALTREP, we must unconditionally clone it before dereferencing,
16-
// otherwise we get a pointer into the ALTREP internals rather than into the
17-
// object it truly represents.
14+
// we indicate that we don't own `x`
1815
static inline SEXP vec_clone_referenced(SEXP x, const enum vctrs_owned owned) {
19-
if (ALTREP(x)) {
20-
return r_clone_referenced(x);
21-
}
22-
2316
if (owned == VCTRS_OWNED_false) {
2417
return r_clone_referenced(x);
2518
} else {

src/slice-assign.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,11 @@ r_obj* vec_assign_switch(r_obj* proxy,
9898
// on a number of factors.
9999
//
100100
// - If a fallback is required, the `proxy` is duplicated at the R level.
101-
// - If `owned` is `VCTRS_OWNED_true`, the `proxy` is typically not duplicated.
102-
// However, if it is an ALTREP object, it is duplicated because we need to be
103-
// able to assign into the object it represents, not the ALTREP r_obj* itself.
101+
// - If `owned` is `VCTRS_OWNED_true`, the `proxy` is not duplicated. If the
102+
// `proxy` happens to be an ALTREP object, materialization will be forced when
103+
// we do the actual assignment, but this should really only happen with
104+
// cheap-to-materialize ALTREP "wrapper" objects since we've claimed that we
105+
// "own" the `proxy`.
104106
// - If `owned` is `VCTRS_OWNED_false`, the `proxy` is only
105107
// duplicated if it is referenced, i.e. `MAYBE_REFERENCED()` returns `true`.
106108
//

0 commit comments

Comments
 (0)