mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
[ruby/json] Optimize fbuffer_append_long
Ref: https://github.com/ruby/json/issues/655 Rather than to write the number backward, and then reverse the buffer, we can start from the back of the buffer and write the number in the proper direction. Before: ``` == Encoding integers (8009 bytes) ruby 3.3.4 (2024-07-09 revisionbe1089c8ec
) +YJIT [arm64-darwin23] Warming up -------------------------------------- json 8.606k i/100ms oj 9.598k i/100ms Calculating ------------------------------------- json 86.059k (± 0.8%) i/s (11.62 μs/i) - 430.300k in 5.000416s oj 97.409k (± 0.6%) i/s (10.27 μs/i) - 489.498k in 5.025360s Comparison: json: 86058.8 i/s oj: 97408.8 i/s - 1.13x faster ``` After: ``` == Encoding integers (8009 bytes) ruby 3.3.4 (2024-07-09 revisionbe1089c8ec
) +YJIT [arm64-darwin23] Warming up -------------------------------------- json (reuse) 9.500k i/100ms json 9.359k i/100ms oj 9.722k i/100ms Calculating ------------------------------------- json (reuse) 96.270k (± 0.4%) i/s (10.39 μs/i) - 484.500k in 5.032777s json 94.800k (± 2.2%) i/s (10.55 μs/i) - 477.309k in 5.037495s oj 97.131k (± 0.7%) i/s (10.30 μs/i) - 486.100k in 5.004822s Comparison: json (reuse): 96270.1 i/s oj: 97130.5 i/s - same-ish: difference falls within error json: 94799.9 i/s - same-ish: difference falls within error ```0655b58d14
This commit is contained in:
parent
b094ee3f23
commit
2e43621806
2 changed files with 10 additions and 17 deletions
|
@ -64,6 +64,7 @@ benchmark_encoding "small nested array", [[1,2,3,4,5]]*10
|
|||
benchmark_encoding "small hash", { "username" => "jhawthorn", "id" => 123, "event" => "wrote json serializer" }
|
||||
|
||||
# On these benchmarks we perform well. Either on par or very closely faster/slower
|
||||
benchmark_encoding "integers", (1_000_000..1_001_000).to_a, except: %i(json_state)
|
||||
benchmark_encoding "mixed utf8", ([("a" * 5000) + "€" + ("a" * 5000)] * 500), except: %i(json_state)
|
||||
benchmark_encoding "mostly utf8", ([("€" * 3333)] * 500), except: %i(json_state)
|
||||
benchmark_encoding "twitter.json", JSON.load_file("#{__dir__}/data/twitter.json"), except: %i(json_state)
|
||||
|
|
|
@ -107,33 +107,25 @@ static void fbuffer_append_char(FBuffer *fb, char newchr)
|
|||
}
|
||||
|
||||
#ifdef JSON_GENERATOR
|
||||
static void freverse(char *start, char *end)
|
||||
{
|
||||
char c;
|
||||
|
||||
while (end > start) {
|
||||
c = *end, *end-- = *start, *start++ = c;
|
||||
}
|
||||
}
|
||||
|
||||
static long fltoa(long number, char *buf)
|
||||
{
|
||||
static char digits[] = "0123456789";
|
||||
static const char digits[] = "0123456789";
|
||||
long sign = number;
|
||||
char* tmp = buf;
|
||||
|
||||
if (sign < 0) number = -number;
|
||||
do *tmp++ = digits[number % 10]; while (number /= 10);
|
||||
if (sign < 0) *tmp++ = '-';
|
||||
freverse(buf, tmp - 1);
|
||||
return tmp - buf;
|
||||
do *tmp-- = digits[number % 10]; while (number /= 10);
|
||||
if (sign < 0) *tmp-- = '-';
|
||||
return buf - tmp;
|
||||
}
|
||||
|
||||
#define LONG_BUFFER_SIZE 20
|
||||
static void fbuffer_append_long(FBuffer *fb, long number)
|
||||
{
|
||||
char buf[20];
|
||||
unsigned long len = fltoa(number, buf);
|
||||
fbuffer_append(fb, buf, len);
|
||||
char buf[LONG_BUFFER_SIZE];
|
||||
char *buffer_end = buf + LONG_BUFFER_SIZE;
|
||||
long len = fltoa(number, buffer_end - 1);
|
||||
fbuffer_append(fb, buffer_end - len, len);
|
||||
}
|
||||
|
||||
static VALUE fbuffer_to_s(FBuffer *fb)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue