Skip to content

Commit 89f816e

Browse files
committed
Make fbuffer_inc_capa easier to inline
With the extra logic added for stack allocation, and especially the memcpy, it became harder for compilers to inline. This doesn't fully reclaim the speed lost with the stack allocation, but it's getting closer. Before: ``` == Encoding twitter.json (466906 bytes) ruby 3.3.4 (2024-07-09 revision be1089c8ec) +YJIT [arm64-darwin23] Warming up -------------------------------------- json 160.000 i/100ms oj 225.000 i/100ms Calculating ------------------------------------- json 1.577k (± 2.0%) i/s (634.20 μs/i) - 8.000k in 5.075561s oj 2.264k (± 2.3%) i/s (441.79 μs/i) - 11.475k in 5.072205s Comparison: json: 1576.8 i/s oj: 2263.5 i/s - 1.44x faster == Encoding citm_catalog.json (500298 bytes) ruby 3.3.4 (2024-07-09 revision be1089c8ec) +YJIT [arm64-darwin23] Warming up -------------------------------------- json 101.000 i/100ms oj 123.000 i/100ms Calculating ------------------------------------- json 1.033k (± 2.6%) i/s (968.06 μs/i) - 5.252k in 5.087617s oj 1.257k (± 2.2%) i/s (795.54 μs/i) - 6.396k in 5.090830s Comparison: json: 1033.0 i/s oj: 1257.0 i/s - 1.22x faster ``` After: ``` == Encoding twitter.json (466906 bytes) ruby 3.3.4 (2024-07-09 revision be1089c8ec) [arm64-darwin23] Warming up -------------------------------------- json 213.000 i/100ms oj 230.000 i/100ms Calculating ------------------------------------- json 2.064k (± 3.6%) i/s (484.44 μs/i) - 10.437k in 5.063685s oj 2.246k (± 0.7%) i/s (445.19 μs/i) - 11.270k in 5.017541s Comparison: json: 2064.2 i/s oj: 2246.2 i/s - 1.09x faster == Encoding citm_catalog.json (500298 bytes) ruby 3.3.4 (2024-07-09 revision be1089c8ec) [arm64-darwin23] Warming up -------------------------------------- json 133.000 i/100ms oj 132.000 i/100ms Calculating ------------------------------------- json 1.327k (± 1.7%) i/s (753.69 μs/i) - 6.650k in 5.013565s oj 1.305k (± 2.2%) i/s (766.40 μs/i) - 6.600k in 5.061089s Comparison: json: 1326.8 i/s oj: 1304.8 i/s - same-ish: difference falls within error ```
1 parent fe607f4 commit 89f816e

File tree

1 file changed

+26
-21
lines changed

1 file changed

+26
-21
lines changed

ext/json/ext/fbuffer/fbuffer.h

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len);
3333
#ifdef JSON_GENERATOR
3434
static void fbuffer_append_long(FBuffer *fb, long number);
3535
#endif
36-
static void fbuffer_append_char(FBuffer *fb, char newchr);
36+
static inline void fbuffer_append_char(FBuffer *fb, char newchr);
3737
#ifdef JSON_GENERATOR
3838
static VALUE fbuffer_to_s(FBuffer *fb);
3939
#endif
@@ -66,29 +66,34 @@ static void fbuffer_clear(FBuffer *fb)
6666
}
6767
#endif
6868

69-
static inline void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
69+
static void fbuffer_do_inc_capa(FBuffer *fb, unsigned long requested)
7070
{
71-
if (RB_UNLIKELY(requested > fb->capa - fb->len)) {
72-
unsigned long required;
71+
unsigned long required;
7372

74-
if (RB_UNLIKELY(!fb->ptr)) {
75-
fb->ptr = ALLOC_N(char, fb->initial_length);
76-
fb->capa = fb->initial_length;
77-
}
73+
if (RB_UNLIKELY(!fb->ptr)) {
74+
fb->ptr = ALLOC_N(char, fb->initial_length);
75+
fb->capa = fb->initial_length;
76+
}
77+
78+
for (required = fb->capa; requested > required - fb->len; required <<= 1);
7879

79-
for (required = fb->capa; requested > required - fb->len; required <<= 1);
80-
81-
if (required > fb->capa) {
82-
if (fb->type == STACK) {
83-
const char *old_buffer = fb->ptr;
84-
fb->ptr = ALLOC_N(char, required);
85-
fb->type = HEAP;
86-
MEMCPY(fb->ptr, old_buffer, char, fb->len);
87-
} else {
88-
REALLOC_N(fb->ptr, char, required);
89-
}
90-
fb->capa = required;
80+
if (required > fb->capa) {
81+
if (fb->type == STACK) {
82+
const char *old_buffer = fb->ptr;
83+
fb->ptr = ALLOC_N(char, required);
84+
fb->type = HEAP;
85+
MEMCPY(fb->ptr, old_buffer, char, fb->len);
86+
} else {
87+
REALLOC_N(fb->ptr, char, required);
9188
}
89+
fb->capa = required;
90+
}
91+
}
92+
93+
static inline void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
94+
{
95+
if (RB_UNLIKELY(requested > fb->capa - fb->len)) {
96+
fbuffer_do_inc_capa(fb, requested);
9297
}
9398
}
9499

@@ -113,7 +118,7 @@ static void fbuffer_append_str(FBuffer *fb, VALUE str)
113118
}
114119
#endif
115120

116-
static void fbuffer_append_char(FBuffer *fb, char newchr)
121+
static inline void fbuffer_append_char(FBuffer *fb, char newchr)
117122
{
118123
fbuffer_inc_capa(fb, 1);
119124
*(fb->ptr + fb->len) = newchr;

0 commit comments

Comments
 (0)