summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2024-09-03 10:40:23 +0200
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2024-10-03 14:20:34 +0900
commit4cd893b0487b9a853a57d1e9cdc461bd0dd6de8f (patch)
tree435380d7fc7a860a302d4bf3480bb181e303ec09
parent57282c62a0df04808d24d63a48be3774f3180763 (diff)
[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
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/11775
-rw-r--r--ext/json/generator/generator.c21
1 files 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);