[flori/json] Optimize fbuffer_inc_capa

On my `JSON.dump` benchmark it shows up as 6% of runtime, compared
to 40% for `convert_UTF8_to_JSON`.

Since the vast majority of the time this function is called we
still have some buffer capacity, we might as well check that
first and skip the expensive loop etc.

With this change my profiler now report this function as 0.7%,
so almost 10x better.

https://github.com/flori/json/commit/a7206bf2db
This commit is contained in:
Jean Boussier 2024-09-02 13:45:38 +02:00 committed by Hiroshi SHIBATA
parent 630c681321
commit 57282c62a0
Notes: git 2024-10-03 05:20:51 +00:00

View File

@ -66,6 +66,10 @@ static FBuffer *fbuffer_dup(FBuffer *fb);
static VALUE fbuffer_to_s(FBuffer *fb);
#endif
#ifndef RB_UNLIKELY
#define RB_UNLIKELY(expr) expr
#endif
static FBuffer *fbuffer_alloc(unsigned long initial_length)
{
FBuffer *fb;
@ -87,20 +91,22 @@ static void fbuffer_clear(FBuffer *fb)
fb->len = 0;
}
static void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
static inline void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
{
unsigned long required;
if (RB_UNLIKELY(requested > fb->capa - fb->len)) {
unsigned long required;
if (!fb->ptr) {
fb->ptr = ALLOC_N(char, fb->initial_length);
fb->capa = fb->initial_length;
}
if (RB_UNLIKELY(!fb->ptr)) {
fb->ptr = ALLOC_N(char, fb->initial_length);
fb->capa = fb->initial_length;
}
for (required = fb->capa; requested > required - fb->len; required <<= 1);
for (required = fb->capa; requested > required - fb->len; required <<= 1);
if (required > fb->capa) {
REALLOC_N(fb->ptr, char, required);
fb->capa = required;
if (required > fb->capa) {
REALLOC_N(fb->ptr, char, required);
fb->capa = required;
}
}
}