Add benchmarking tool + improve integer formatting performance
Typical priorities: make it fast before fixing all the bugs. *shrug*
This commit is contained in:
parent
c16a9fa493
commit
9c8ce3f782
4 changed files with 259 additions and 13 deletions
35
c/jsonfmt.c
35
c/jsonfmt.c
|
|
@ -5,7 +5,11 @@ static void fujson_fmt_str(fustr *out, const char *stri, size_t len, int utf8) {
|
|||
const unsigned char *str = (const unsigned char *)stri;
|
||||
unsigned char x = 0;
|
||||
|
||||
/* Validate entire string for conformance if this is flagged as a utf8 string, this lets us be lazy further on. */
|
||||
/* Validate entire string for conformance if this is flagged as a utf8
|
||||
* string, this lets us be lazy further on.
|
||||
* Commenting this out doubles the performance for formatting unicode
|
||||
* strings, I suspect there's room for optimizations in
|
||||
* is_c9strict_utf8_string(). */
|
||||
if (utf8 && !is_c9strict_utf8_string(str, len)) {
|
||||
return; /* TODO: Throw error. */
|
||||
}
|
||||
|
|
@ -63,9 +67,22 @@ static void fujson_fmt_str(fustr *out, const char *stri, size_t len, int utf8) {
|
|||
fustr_write(out, "\"", 1);
|
||||
}
|
||||
|
||||
/* All digits between 0 and 100, a trick I borrowed from the Zig stdlib. */
|
||||
static const char fujson_digits[] =
|
||||
"00010203040506070809"
|
||||
"10111213141516171819"
|
||||
"20212223242526272829"
|
||||
"30313233343536373839"
|
||||
"40414243444546474849"
|
||||
"50515253545556575859"
|
||||
"60616263646566676869"
|
||||
"70717273747576777879"
|
||||
"80818283848586878889"
|
||||
"90919293949596979899";
|
||||
|
||||
static void fujson_fmt_int(fustr *out, SV *val) {
|
||||
char buf[32];
|
||||
size_t idx = 32;
|
||||
char *r = buf+31;
|
||||
int neg = 0;
|
||||
IV iv;
|
||||
UV uv;
|
||||
|
|
@ -83,13 +100,15 @@ static void fujson_fmt_int(fustr *out, SV *val) {
|
|||
return;
|
||||
}
|
||||
|
||||
while (uv > 0) {
|
||||
/* TODO: can use a lookup table to optimize for 0 - 100; need benchmark */
|
||||
buf[--idx] = '0' + (uv % 10);
|
||||
uv /= 10;
|
||||
while (uv >= 10) {
|
||||
r -= 2;
|
||||
memcpy(r, fujson_digits + ((uv % 100)<<1), 2);
|
||||
uv /= 100;
|
||||
}
|
||||
if (neg) buf[--idx] = '-';
|
||||
fustr_write(out, buf+idx, sizeof buf - idx);
|
||||
if (uv > 0) *(--r) = '0' + (uv % 10);
|
||||
if (neg) *(--r) = '-';
|
||||
uv = 31 - (r - buf);
|
||||
fustr_write(out, r, uv);
|
||||
}
|
||||
|
||||
static void fujson_fmt_av(fustr *out, AV *av) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue