Make self-search special code only depend on cell size
This commit is contained in:
parent
5bf4e20ead
commit
57d33990e3
@ -7,12 +7,11 @@ B memberOf_c1(B t, B x) {
|
||||
if (isAtm(x) || RNK(x)==0) thrM("∊: Argument cannot have rank 0");
|
||||
usz n = *SH(x);
|
||||
if (n==0) { decG(x); return emptyIVec(); }
|
||||
if (RNK(x)>1) x = toCells(x);
|
||||
u8 xe = TI(x,elType);
|
||||
if (elChr(xe)) xe -= el_c8-el_i8;
|
||||
|
||||
u8 lw = cellWidthLog(x);
|
||||
void* xv = tyany_ptr(x);
|
||||
#define BRUTE(T) \
|
||||
i##T* xp = tyany_ptr(x); \
|
||||
i##T* xp = xv; \
|
||||
u64* rp; B r = m_bitarrv(&rp, n); bitp_set(rp, 0, 1); \
|
||||
for (usz i=1; i<n; i++) { \
|
||||
bool c=1; i##T xi=xp[i]; \
|
||||
@ -22,7 +21,7 @@ B memberOf_c1(B t, B x) {
|
||||
decG(x); return r;
|
||||
#define LOOKUP(T) \
|
||||
usz tn = 1<<T; \
|
||||
u##T* xp = (u##T*)tyany_ptr(x); \
|
||||
u##T* xp = (u##T*)xv; \
|
||||
i8* rp; B r = m_i8arrv(&rp, n); \
|
||||
TALLOC(u8, tab, tn); \
|
||||
if (T>8 && n<tn/64) for (usz i=0; i<n; i++) tab[xp[i]]=1; \
|
||||
@ -30,14 +29,14 @@ B memberOf_c1(B t, B x) {
|
||||
for (usz i=0; i<n; i++) { u##T j=xp[i]; rp[i]=tab[j]; tab[j]=0; } \
|
||||
decG(x); TFREE(tab); \
|
||||
return num_squeeze(r)
|
||||
if (xe==el_i8) { if (n<8) { BRUTE(8); } else { LOOKUP(8); } }
|
||||
if (xe==el_i16) { if (n<8) { BRUTE(16); } else { LOOKUP(16); } }
|
||||
if (lw == 3) { if (n<8) { BRUTE(8); } else { LOOKUP(8); } }
|
||||
if (lw == 4) { if (n<8) { BRUTE(16); } else { LOOKUP(16); } }
|
||||
#undef LOOKUP
|
||||
if (xe==el_i32) {
|
||||
if (lw == 5) {
|
||||
if (n<=32) { BRUTE(32); }
|
||||
// Radix-assisted lookup
|
||||
usz rx = 256, tn = 1<<16; // Radix; table length
|
||||
u32* v0 = (u32*)tyany_ptr(x);
|
||||
u32* v0 = (u32*)xv;
|
||||
i8* r0; B r = m_i8arrv(&r0, n);
|
||||
|
||||
TALLOC(u8, alloc, 6*n+(4+(tn>3*n?tn:3*n)+(2*rx+1)*sizeof(usz)));
|
||||
@ -81,6 +80,7 @@ B memberOf_c1(B t, B x) {
|
||||
}
|
||||
#undef BRUTE
|
||||
|
||||
if (RNK(x)>1) x = toCells(x);
|
||||
u64* rp; B r = m_bitarrv(&rp, n);
|
||||
H_Sb* set = m_Sb(64);
|
||||
SGetU(x)
|
||||
@ -94,12 +94,11 @@ B count_c1(B t, B x) {
|
||||
usz n = *SH(x);
|
||||
if (n==0) { decG(x); return emptyIVec(); }
|
||||
if (n>(usz)I32_MAX+1) thrM("⊒: Argument length >2⋆31 not supported");
|
||||
if (RNK(x)>1) x = toCells(x);
|
||||
u8 xe = TI(x,elType);
|
||||
if (elChr(xe)) xe -= el_c8-el_i8;
|
||||
|
||||
u8 lw = cellWidthLog(x);
|
||||
void* xv = tyany_ptr(x);
|
||||
#define BRUTE(T) \
|
||||
i##T* xp = tyany_ptr(x); \
|
||||
i##T* xp = xv; \
|
||||
i8* rp; B r = m_i8arrv(&rp, n); rp[0]=0; \
|
||||
for (usz i=1; i<n; i++) { \
|
||||
usz c=0; i##T xi=xp[i]; \
|
||||
@ -109,7 +108,7 @@ B count_c1(B t, B x) {
|
||||
decG(x); return r;
|
||||
#define LOOKUP(T) \
|
||||
usz tn = 1<<T; \
|
||||
u##T* xp = (u##T*)tyany_ptr(x); \
|
||||
u##T* xp = (u##T*)xv; \
|
||||
i32* rp; B r = m_i32arrv(&rp, n); \
|
||||
TALLOC(i32, tab, tn); \
|
||||
if (T>8 && n<tn/16) for (usz i=0; i<n; i++) tab[xp[i]]=0; \
|
||||
@ -117,14 +116,14 @@ B count_c1(B t, B x) {
|
||||
for (usz i=0; i<n; i++) rp[i]=tab[xp[i]]++; \
|
||||
decG(x); TFREE(tab); \
|
||||
return num_squeeze(r)
|
||||
if (xe==el_i8) { if (n<12) { BRUTE(8); } else { LOOKUP(8); } }
|
||||
if (xe==el_i16) { if (n<12) { BRUTE(16); } else { LOOKUP(16); } }
|
||||
if (lw==3) { if (n<12) { BRUTE(8); } else { LOOKUP(8); } }
|
||||
if (lw==4) { if (n<12) { BRUTE(16); } else { LOOKUP(16); } }
|
||||
#undef LOOKUP
|
||||
if (xe==el_i32) {
|
||||
if (lw==5) {
|
||||
if (n<=32) { BRUTE(32); }
|
||||
// Radix-assisted lookup
|
||||
usz rx = 256, tn = 1<<16; // Radix; table length
|
||||
u32* v0 = (u32*)tyany_ptr(x);
|
||||
u32* v0 = (u32*)xv;
|
||||
i32* r0; B r = m_i32arrv(&r0, n);
|
||||
|
||||
TALLOC(u8, alloc, 6*n+(4+4*(tn>n?tn:n)+(2*rx+1)*sizeof(usz)));
|
||||
@ -169,6 +168,7 @@ B count_c1(B t, B x) {
|
||||
}
|
||||
#undef BRUTE
|
||||
|
||||
if (RNK(x)>1) x = toCells(x);
|
||||
i32* rp; B r = m_i32arrv(&rp, n);
|
||||
H_b2i* map = m_b2i(64);
|
||||
SGetU(x)
|
||||
@ -186,12 +186,11 @@ B indexOf_c1(B t, B x) {
|
||||
usz n = *SH(x);
|
||||
if (n==0) { decG(x); return emptyIVec(); }
|
||||
if (n>(usz)I32_MAX+1) thrM("⊐: Argument length >2⋆31 not supported");
|
||||
if (RNK(x)>1) x = toCells(x);
|
||||
u8 xe = TI(x,elType);
|
||||
if (elChr(xe)) xe -= el_c8-el_i8;
|
||||
|
||||
u8 lw = cellWidthLog(x);
|
||||
void* xv = tyany_ptr(x);
|
||||
#define BRUTE(T) \
|
||||
i##T* xp = tyany_ptr(x); \
|
||||
i##T* xp = xv; \
|
||||
i8* rp; B r = m_i8arrv(&rp, n); rp[0]=0; \
|
||||
TALLOC(i##T, uniq, n); uniq[0]=xp[0]; \
|
||||
for (usz i=1, u=1; i<n; i++) { \
|
||||
@ -202,7 +201,7 @@ B indexOf_c1(B t, B x) {
|
||||
decG(x); TFREE(uniq); return r;
|
||||
#define LOOKUP(T) \
|
||||
usz tn = 1<<T; \
|
||||
u##T* xp = (u##T*)tyany_ptr(x); \
|
||||
u##T* xp = (u##T*)xv; \
|
||||
i32* rp; B r = m_i32arrv(&rp, n); \
|
||||
TALLOC(i32, tab, tn); \
|
||||
if (T>8 && n<tn/16) for (usz i=0; i<n; i++) tab[xp[i]]=n; \
|
||||
@ -214,11 +213,11 @@ B indexOf_c1(B t, B x) {
|
||||
} \
|
||||
decG(x); TFREE(tab); \
|
||||
return num_squeeze(r)
|
||||
if (xe==el_i8) { if (n<12) { BRUTE(8); } else { LOOKUP(8); } }
|
||||
if (xe==el_i16) { if (n<12) { BRUTE(16); } else { LOOKUP(16); } }
|
||||
if (lw==3) { if (n<12) { BRUTE(8); } else { LOOKUP(8); } }
|
||||
if (lw==4) { if (n<12) { BRUTE(16); } else { LOOKUP(16); } }
|
||||
#undef LOOKUP
|
||||
|
||||
if (xe==el_i32) {
|
||||
if (lw==5) {
|
||||
if (n<32) { BRUTE(32); }
|
||||
i32* xp = tyany_ptr(x);
|
||||
i32 min=I32_MAX, max=I32_MIN;
|
||||
@ -245,6 +244,7 @@ B indexOf_c1(B t, B x) {
|
||||
}
|
||||
#undef BRUTE
|
||||
|
||||
if (RNK(x)>1) x = toCells(x);
|
||||
i32* rp; B r = m_i32arrv(&rp, n);
|
||||
H_b2i* map = m_b2i(64);
|
||||
SGetU(x)
|
||||
|
||||
@ -54,4 +54,17 @@ extern u8 elType2type[];
|
||||
extern u8 elTypeWidth[];
|
||||
#define elWidth(X) elTypeWidth[X]
|
||||
extern u8 arrTypeWidthLog[];
|
||||
#define arrTypeWidthLog(X) arrTypeWidthLog[X]
|
||||
#define arrTypeWidthLog(X) arrTypeWidthLog[X]
|
||||
extern u8 arrTypeBitsLog[];
|
||||
#define arrTypeBitsLog(X) arrTypeBitsLog[X]
|
||||
|
||||
// Log of width in bits: max of 7, and also return 7 if not power of 2
|
||||
static u8 cellWidthLog(B x) {
|
||||
assert(isArr(x) && RNK(x)>=1);
|
||||
u8 lw = arrTypeBitsLog(TY(x));
|
||||
if (LIKELY(RNK(x)==1)) return lw;
|
||||
usz csz = arr_csz(x);
|
||||
if (csz & (csz-1)) return 7; // Not power of 2
|
||||
lw += CTZ(csz);
|
||||
return lw<7? lw : 7;
|
||||
}
|
||||
|
||||
@ -20,6 +20,14 @@ u8 arrTypeWidthLog[] = {
|
||||
[t_i32arr]=2, [t_i32slice]=2, [t_c32arr]=2, [t_c32slice]=2,
|
||||
[t_f64arr]=3, [t_f64slice]=3
|
||||
};
|
||||
u8 arrTypeBitsLog[] = {
|
||||
[t_bitarr]=0,
|
||||
[t_i8arr ]=3, [t_i8slice ]=3, [t_c8arr ]=3, [t_c8slice ]=3,
|
||||
[t_i16arr]=4, [t_i16slice]=4, [t_c16arr]=4, [t_c16slice]=4,
|
||||
[t_i32arr]=5, [t_i32slice]=5, [t_c32arr]=5, [t_c32slice]=5,
|
||||
[t_f64arr]=6, [t_f64slice]=6,
|
||||
[t_harr ]=6, [t_hslice ]=6, [t_fillarr]=6,[t_fillslice]=6
|
||||
};
|
||||
|
||||
B m_i8(i8 x) { return m_i32(x); } B m_i16(i16 x) { return m_i32(x); }
|
||||
B m_c8(u8 x) { return m_c32(x); } B m_c16(u16 x) { return m_c32(x); }
|
||||
@ -87,4 +95,4 @@ void tyarr_init() {
|
||||
Arr* emptySVec = arr_shVec(m_fillarrp(0));
|
||||
fillarr_setFill(emptySVec, emptyCVec());
|
||||
bi_emptySVec = taga(emptySVec); gc_add(bi_emptySVec);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user