From 12cc7af83d1f16667799155f1fa23a5c4c426da5 Mon Sep 17 00:00:00 2001 From: dzaima Date: Mon, 7 Oct 2024 05:44:41 +0300 Subject: [PATCH] fast path for squeeze target determining on sorted input --- src/builtins/squeeze.c | 32 +++++++++++++++++++++++++++++--- src/core/stuff.h | 14 ++++++++------ 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/builtins/squeeze.c b/src/builtins/squeeze.c index 6809af18..6120ae72 100644 --- a/src/builtins/squeeze.c +++ b/src/builtins/squeeze.c @@ -169,10 +169,36 @@ B chr_squeeze(B x) { /*when known typed:*/ r_x: return FL_SET(x, fl_squoze); } -B any_squeeze(B x) { +NOINLINE B int_squeeze_sorted(B x) { + usz xia = IA(x); + if (xia==0) { + already_squoze:; + return FL_SET(x, fl_squoze); + } + SGetU(x); + u8 x0e = selfElType_i32(o2iG(GetU(x, 0))); + u8 x1e = selfElType_i32(o2iG(GetU(x, xia-1))); + u8 xse = x0e>x1e? x0e : x1e; + u8 xe = TI(x,elType); + if (xe == xse) goto already_squoze; + Arr* ra; + switch (xse) { default: UD; + case el_i16: ra = (Arr*)cpyI16Arr(x); break; + case el_i8: ra = (Arr*)cpyI8Arr (x); break; + case el_bit: ra = (Arr*)cpyBitArr(x); break; + } + return taga(FLV_SET(ra, fl_squoze)); +} + +NOINLINE B any_squeeze(B x) { assert(isArr(x)); - if (FL_HAS(x,fl_squoze)) return x; - if (IA(x)==0) return FL_SET(x, fl_squoze); // TODO return a version of the smallest type + if (FL_HAS(x, fl_squoze|fl_asc|fl_dsc)) { + if (FL_HAS(x, fl_squoze)) return x; + u8 xe = TI(x,elType); + if (elInt(xe)) return int_squeeze_sorted(x); + // could check for sorted character arrays (even from a TI(x,el_B) input) but sorted character arrays aren't worth it + } + if (IA(x)==0) return FL_SET(x, fl_squoze); // TODO return a version of the smallest type? B x0 = IGetU(x, 0); if (isNum(x0)) return num_squeeze(x); else if (isC32(x0)) return chr_squeeze(x); diff --git a/src/core/stuff.h b/src/core/stuff.h index 448feb8d..cc7420ed 100644 --- a/src/core/stuff.h +++ b/src/core/stuff.h @@ -219,16 +219,18 @@ static usz uszMul(usz a, usz b) { return a; } +static u8 selfElType_i32(i32 i) { + return i==(i8)i? (i==(i&1)? el_bit : el_i8) : (i==(i16)i? el_i16 : el_i32); +} +static u8 selfElType_c32(u32 c) { + return LIKELY(c<=255)? el_c8 : c<=65535? el_c16 : el_c32; +} static u8 selfElType(B x) { // guaranteed to fit fill if (isF64(x)) { if (!q_i32(x)) return el_f64; - i32 i = o2iG(x); - return i==(i8)i? (i==(i&1)? el_bit : el_i8) : (i==(i16)i? el_i16 : el_i32); - } - if (isC32(x)) { - u32 c = o2cG(x); - return LIKELY(c<=255)? el_c8 : c<=65535? el_c16 : el_c32; + return selfElType_i32(o2iG(x)); } + if (isC32(x)) return selfElType_c32(o2cG(x)); return el_B; } static bool elChr(u8 x) { return x>=el_c8 && x<=el_c32; }