From 4cd893b0487b9a853a57d1e9cdc461bd0dd6de8f Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Tue, 3 Sep 2024 10:40:23 +0200 Subject: [PATCH] [flori/json] Optimize key type check in `json_object_i` Rather than checking the class we can check the type. This is very subtly different for String subclasses, but I think it's OK. We also save on checking the type again in the fast path. https://github.com/flori/json/commit/772a0201ab --- ext/json/generator/generator.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c index 9ecbfbeaa0..b8734764c7 100644 --- a/ext/json/generator/generator.c +++ b/ext/json/generator/generator.c @@ -814,7 +814,6 @@ json_object_i(VALUE key, VALUE val, VALUE _arg) long delim2_len = FBUFFER_LEN(state->object_delim2); long depth = state->depth; int j; - VALUE klass, key_to_s; if (arg->iter > 0) fbuffer_append(buffer, delim, delim_len); if (object_nl) { @@ -826,15 +825,19 @@ json_object_i(VALUE key, VALUE val, VALUE _arg) } } - klass = CLASS_OF(key); - if (klass == rb_cString) { - key_to_s = key; - } else if (klass == rb_cSymbol) { - key_to_s = rb_sym2str(key); - } else { - key_to_s = rb_funcall(key, i_to_s, 0); + VALUE key_to_s; + switch(rb_type(key)) { + case T_STRING: + key_to_s = key; + break; + case T_SYMBOL: + key_to_s = rb_sym2str(key); + break; + default: + key_to_s = rb_convert_type(key, T_STRING, "String", "to_s"); + break; } - Check_Type(key_to_s, T_STRING); + generate_json(buffer, Vstate, state, key_to_s); fbuffer_append(buffer, delim2, delim2_len); generate_json(buffer, Vstate, state, val);