diff options
| author | Jean Boussier <jean.boussier@gmail.com> | 2024-09-03 10:40:23 +0200 |
|---|---|---|
| committer | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2024-10-03 14:20:34 +0900 |
| commit | 4cd893b0487b9a853a57d1e9cdc461bd0dd6de8f (patch) | |
| tree | 435380d7fc7a860a302d4bf3480bb181e303ec09 | |
| parent | 57282c62a0df04808d24d63a48be3774f3180763 (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.c | 21 |
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); |
