diff --git a/src/builtins/select.c b/src/builtins/select.c index 28737a28..726131ea 100644 --- a/src/builtins/select.c +++ b/src/builtins/select.c @@ -138,7 +138,7 @@ static NOINLINE DirectArr toFillArr(B x, B fill) { return (DirectArr){taga(r), rp}; } static void* reusableArr_ptr(Arr* t, u8 el) { - return el==el_B? (void*)harrv_ptr(t) : tyarrv_ptr((TyArr*)t); + return el==el_B? (void*)(PTY(t)==t_fillarr? fillarrv_ptr(t) : harrv_ptr(t)) : tyarrv_ptr((TyArr*)t); } static DirectArr toEltypeArr(B x, u8 re) { // consumes x; returns an array with eltype==re, with same shape/elements/fill as x, and its data pointer assert(isArr(x)); @@ -513,7 +513,7 @@ B select_replace(u32 chr, B w, B x, B rep, usz wia, usz cam, usz csz) { // consu u8 we = TI(w,elType); assert(elNum(we) || wia==0); u8 xe = TI(x,elType); u8 re = el_or(xe, TI(rep,elType)); - Arr* ra; + Arr* ra; B rb; // w = taga(cpyF64Arr(w)); we = el_f64; // test the float path if (we==el_f64) { f64* wp = f64any_ptr(w); @@ -546,23 +546,23 @@ B select_replace(u32 chr, B w, B x, B rep, usz wia, usz cam, usz csz) { // consu } assert(elInt(we) || wia==0); + DirectArr r = toEltypeArr(x, re); rb = r.obj; w = toI32Any(w); i32* wp = i32any_ptr(w); SPARSE_INIT(wp[i]) - bool reuse = reusable(x) && re==reuseElType[TY(x)]; SLOWIF(!reuse && cam>100 && wiafns == &mutFns[el_MAX]); - if (reusable(x) && reuseElType[TY(x)]==el) { + if (reusable(x) && reuseElType[TY(x)]==el && TY(x)!=t_fillarr) { // reuseElType is currently primarily used for toEltypeArr; currently just leaving this special-cased until it's decided what to do with this m->fns = &mutFns[el]; Arr* a = m->val = a(REUSE(x)); m->a = harr_tyarr_ptr(a, el); @@ -834,6 +834,7 @@ void mutF_init(void) { mutFns[el_c32].elType = el_c32; mutFns[el_c32].valType = t_c32arr; reuseElType[t_c32arr] = el_c32; mutFns[el_f64].elType = el_f64; mutFns[el_f64].valType = t_f64arr; reuseElType[t_f64arr] = el_f64; mutFns[el_B ].elType = el_B ; mutFns[el_B ].valType = t_harr; reuseElType[t_harr] = el_B; + /* and fillarr also to complete being able to reuse any target */ reuseElType[t_fillarr]= el_B; mutFns[el_MAX].elType = el_MAX; mutFns[el_MAX].valType = t_COUNT; for (u8 i = 0; i < el_MAX; i++) copyFns[i] = mutFns[i].m_copyG; for (u8 i = 0; i < el_MAX; i++) fillFns[i] = mutFns[i].m_fillG; diff --git a/test/cases/perf.bqn b/test/cases/perf.bqn index ac0aa54d..05840217 100644 --- a/test/cases/perf.bqn +++ b/test/cases/perf.bqn @@ -32,7 +32,9 @@ # in-place ⌾(l⊸⊏) list %USE fastone ⋄ a←⋈¨5+↕1e6 ⋄ n←{𝕊: a 1⊸+⌾(1‿3‿3‿¯1⊸⊏)↩}_fastone 4 ⋄ ! (⋈¨5‿6‿7‿8‿9‿1000000‿1000001‿1000002‿1000003‿1000004+0‿n‿0‿n‿0‿0‿0‿0‿0‿n) ≡ (5↑a)∾¯5↑a %!DEBUG %USE fastone ⋄ a←5+↕1e6 ⋄ n←{𝕊: a 1⊸+⌾(1‿3‿3‿¯1⊸⊏)↩}_fastone 4 ⋄ ! ( 5‿6‿7‿8‿9‿1000000‿1000001‿1000002‿1000003‿1000004+0‿n‿0‿n‿0‿0‿0‿0‿0‿n) ≡ (5↑a)∾¯5↑a %!DEBUG -%USE fastone ⋄ a←5+1e6⥊@+↕10000 ⋄ n←{𝕊: a 1⊸+⌾(1‿3‿3‿¯1⊸⊏)↩}_fastone 4 ⋄ ! (@+5‿6‿7‿8‿9‿10000‿10001‿10002‿10003‿10004 +0‿n‿0‿n‿0‿0‿0‿0‿0‿n) ≡ (5↑a)∾¯5↑a %!DEBUG +%USE fastone ⋄ a←5+1e6⥊@+↕10000 ⋄ n←{𝕊: a 1⊸+⌾(1‿3‿3‿¯1⊸⊏)↩}_fastone 4 ⋄ ! (@+5‿6‿7‿8‿9‿10000‿10001‿10002‿10003‿10004 +0‿n‿0‿n‿0‿0‿0‿0‿0‿n) ≡ (5↑a)∾¯5↑a %!DEBUG +%USE fastone ⋄ a←5+1e6⥊@+↕10000 ⋄ n←{𝕊: a'?'¨⌾(1‿3‿3‿¯1⊸⊏)↩}_fastone 4 ⋄ ! (@+5‿6‿7‿8‿9‿10000‿10001‿10002‿10003‿10004{𝕩?63; 𝕨}¨0‿1‿0‿1‿0‿0‿0‿0‿0‿1) ≡ (5↑a)∾¯5↑a %!DEBUG +%USE fastone ⋄ a←5+1e6⥊@+↕10000 ⋄ n←{𝕊: a 99¨⌾(1‿3‿3‿¯1⊸⊏)↩}_fastone 4 ⋄ ! ( 5‿6‿7‿8‿9‿10000‿10001‿10002‿10003‿10004{𝕩?99;@+𝕨}¨0‿1‿0‿1‿0‿0‿0‿0‿0‿1) ≡ (5↑a)∾¯5↑a %!DEBUG # in-place ⌾(l⊸⊏) highrank %USE fastone ⋄ a←∘‿2‿2⥊⋈¨5+↕1e6 ⋄ n←{𝕊: a 1⊸+⌾(1‿3‿3‿¯1⊸⊏)↩}_fastone 4 ⋄ ! a ≡ (n×⟨1,3,¯1+≠a⟩∊˜↕≠a) + ∘‿2‿2⥊⋈¨5+↕1e6 %!DEBUG