speeded up moo_inttostr()

This commit is contained in:
hyunghwan.chung 2019-03-29 17:16:03 +00:00
parent 93f6847034
commit 608bbb4a91
2 changed files with 73 additions and 34 deletions

View File

@ -4276,7 +4276,6 @@ oops:
return MOO_NULL; return MOO_NULL;
} }
moo_oop_t moo_absint (moo_t* moo, moo_oop_t x) moo_oop_t moo_absint (moo_t* moo, moo_oop_t x)
{ {
if (MOO_OOP_IS_SMOOI(x)) if (MOO_OOP_IS_SMOOI(x))
@ -4307,7 +4306,7 @@ moo_oop_t moo_absint (moo_t* moo, moo_oop_t x)
return x; return x;
} }
static moo_liw_t div_with_carry (moo_liw_t x, moo_liw_t y, moo_liw_t* r) static MOO_INLINE moo_liw_t div_with_carry (moo_liw_t x, moo_liw_t y, moo_liw_t* r)
{ {
/* TODO: optimize it with ASM */ /* TODO: optimize it with ASM */
moo_liw_t q; moo_liw_t q;
@ -4321,39 +4320,43 @@ static moo_liw_t div_with_carry (moo_liw_t x, moo_liw_t y, moo_liw_t* r)
return q; return q;
} }
static get_last_digit (moo_t* moo, moo_liw_t* x, moo_oow_t xs, int base) static MOO_INLINE moo_liw_t get_last_digit (moo_t* moo, moo_liw_t* x, moo_oow_t* xs, int radix)
{ {
moo_oow_t i = xs; /* this function changes the contents of the large integer word array */
moo_liw_t r = 0; moo_oow_t oxs = *xs;
while (i > 0) moo_liw_t carry = 0;
moo_oow_t i;
moo_lidw_t dw;
MOO_ASSERT (moo, oxs > 0);
for (i = oxs; i > 0; )
{ {
--i; --i;
x[i] = div_with_carry(x[i], base, &r); #if 0
x[i] = div_with_carry(x[i], radix, &carry);
#else
dw = ((moo_lidw_t)carry << MOO_LIW_BITS) + x[i];
/* TODO: optimize it with ASM - no seperate / and % */
x[i] = dw / radix;
carry = dw % radix;
#endif
} }
return r; if (/*oxs > 0 &&*/ x[oxs - 1] == 0) *xs = oxs - 1;
return carry;
} }
void test_last_digit (moo_t* moo)
{
moo_ooch_t x[] = { 'F','F','9','9','1', '2','3','4',
'F','F','9','9','1', '2','3','4',
'F','F','9','9','1', '2','3','4',
'F','F','9','9','1', '2','3','4',
'F','F','9','9','1', '2','3','4',
'F','F','9','9','1', '2','3','4',
'F','F','9','9','1', '2','3','4',
'F','F','9','9','1', '2','3','4',
'F','F','9','9','1', '2','3','4' };
moo_oop_t q = moo_strtoint (moo, x, MOO_COUNTOF(x), 16);
moo_oop_t s = moo_inttostr (moo, q, 10);
MOO_DEBUG1 (moo, "[%O]\n", s);
}
moo_oop_t moo_inttostr (moo_t* moo, moo_oop_t num, int flagged_radix) moo_oop_t moo_inttostr (moo_t* moo, moo_oop_t num, int flagged_radix)
{ {
moo_ooi_t v = 0; moo_ooi_t v = 0;
moo_oow_t w; moo_oow_t w;
moo_oow_t as, bs, rs; moo_oow_t as;
/*#define INTTOSTR_SLOW_WORD_BY_WORD_CONVERSION*/
#if defined(INTTOSTR_SLOW_WORD_BY_WORD_CONVERSION)
moo_oow_t bs, rs;
#if (MOO_LIW_BITS == MOO_OOW_BITS) #if (MOO_LIW_BITS == MOO_OOW_BITS)
moo_liw_t b[1]; moo_liw_t b[1];
#elif (MOO_LIW_BITS == MOO_OOHW_BITS) #elif (MOO_LIW_BITS == MOO_OOHW_BITS)
@ -4362,9 +4365,11 @@ moo_oop_t moo_inttostr (moo_t* moo, moo_oop_t num, int flagged_radix)
# error UNSUPPORTED LIW BIT SIZE # error UNSUPPORTED LIW BIT SIZE
#endif #endif
moo_liw_t* a, * q, * r; moo_liw_t* a, * q, * r;
#endif
moo_liw_t* t = MOO_NULL; moo_liw_t* t = MOO_NULL;
moo_ooch_t* xbuf = MOO_NULL; moo_ooch_t* xbuf = MOO_NULL;
moo_oow_t xlen = 0, seglen, reqcapa; moo_oow_t xlen = 0, reqcapa;
int radix; int radix;
const char* _digitc; const char* _digitc;
@ -4412,6 +4417,7 @@ moo_oop_t moo_inttostr (moo_t* moo, moo_oop_t num, int flagged_radix)
as = MOO_OBJ_GET_SIZE(num); as = MOO_OBJ_GET_SIZE(num);
#if defined(INTTOSTR_SLOW_WORD_BY_WORD_CONVERSION)
if (IS_POW2(radix)) if (IS_POW2(radix))
{ {
unsigned int exp, accbits; unsigned int exp, accbits;
@ -4480,7 +4486,6 @@ moo_oop_t moo_inttostr (moo_t* moo, moo_oop_t num, int flagged_radix)
/* Do it in a hard way for other cases */ /* Do it in a hard way for other cases */
/* TODO: find an optimial buffer size */
/* TODO: find an optimial buffer size */ /* TODO: find an optimial buffer size */
reqcapa = as * MOO_LIW_BITS + 1; reqcapa = as * MOO_LIW_BITS + 1;
if (moo->inttostr.xbuf.capa < reqcapa) if (moo->inttostr.xbuf.capa < reqcapa)
@ -4519,14 +4524,17 @@ moo_oop_t moo_inttostr (moo_t* moo, moo_oop_t num, int flagged_radix)
# error UNSUPPORTED LIW BIT SIZE # error UNSUPPORTED LIW BIT SIZE
#endif #endif
a = &t[0]; a = &t[0]; /* temporary space for the number to convert */
q = &t[as]; q = &t[as]; /* temporary space for intermediate quotient */
r = &t[as * 2]; r = &t[as * 2]; /* temporary space for intermediate remainder */
MOO_MEMCPY (a, MOO_OBJ_GET_LIWORD_SLOT(num), MOO_SIZEOF(*a) * as); MOO_MEMCPY (a, MOO_OBJ_GET_LIWORD_SLOT(num), MOO_SIZEOF(*a) * as);
do do
{ {
moo_oow_t seglen;
/* NOTE: this loop is super-slow */
if (is_less_unsigned_array(b, bs, a, as)) if (is_less_unsigned_array(b, bs, a, as))
{ {
moo_liw_t* tmp; moo_liw_t* tmp;
@ -4576,6 +4584,41 @@ moo_oop_t moo_inttostr (moo_t* moo, moo_oop_t num, int flagged_radix)
} }
} }
while (1); while (1);
#else
reqcapa = as * MOO_LIW_BITS + 1;
if (moo->inttostr.xbuf.capa < reqcapa)
{
xbuf = (moo_ooch_t*)moo_reallocmem(moo, moo->inttostr.xbuf.ptr, reqcapa * MOO_SIZEOF(*xbuf));
if (!xbuf) return MOO_NULL;
moo->inttostr.xbuf.capa = reqcapa;
moo->inttostr.xbuf.ptr = xbuf;
}
else
{
xbuf = moo->inttostr.xbuf.ptr;
}
if (moo->inttostr.t.capa < as)
{
t = (moo_liw_t*)moo_reallocmem(moo, moo->inttostr.t.ptr, reqcapa * MOO_SIZEOF(*t));
if (!t) return MOO_NULL;
moo->inttostr.t.capa = as;
moo->inttostr.t.ptr = t;
}
else
{
t = moo->inttostr.t.ptr;
}
MOO_MEMCPY (t, MOO_OBJ_GET_LIWORD_SLOT(num), MOO_SIZEOF(*t) * as);
do
{
moo_liw_t dv = get_last_digit(moo, t, &as, radix);
xbuf[xlen++] = _digitc[dv];
}
while (as > 0);
#endif
if (MOO_POINTER_IS_NBIGINT(moo, num)) xbuf[xlen++] = '-'; if (MOO_POINTER_IS_NBIGINT(moo, num)) xbuf[xlen++] = '-';
reverse_string (xbuf, xlen); reverse_string (xbuf, xlen);

View File

@ -272,10 +272,6 @@ int main (int argc, char* argv[])
signal (SIGTERM, SIG_IGN); signal (SIGTERM, SIG_IGN);
#endif #endif
/*
test_last_digit (moo);
exit (0);
*/
moo_catch_termreq (); moo_catch_termreq ();
moo_start_ticker (); moo_start_ticker ();