Skip to content

Commit 772a020

Browse files
committed
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.
1 parent 572aa64 commit 772a020

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

ext/json/ext/generator/generator.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,6 @@ json_object_i(VALUE key, VALUE val, VALUE _arg)
847847
long delim2_len = FBUFFER_LEN(state->object_delim2);
848848
long depth = state->depth;
849849
int j;
850-
VALUE klass, key_to_s;
851850

852851
if (arg->iter > 0) fbuffer_append(buffer, delim, delim_len);
853852
if (object_nl) {
@@ -859,15 +858,19 @@ json_object_i(VALUE key, VALUE val, VALUE _arg)
859858
}
860859
}
861860

862-
klass = CLASS_OF(key);
863-
if (klass == rb_cString) {
864-
key_to_s = key;
865-
} else if (klass == rb_cSymbol) {
866-
key_to_s = rb_sym2str(key);
867-
} else {
868-
key_to_s = rb_funcall(key, i_to_s, 0);
861+
VALUE key_to_s;
862+
switch(rb_type(key)) {
863+
case T_STRING:
864+
key_to_s = key;
865+
break;
866+
case T_SYMBOL:
867+
key_to_s = rb_sym2str(key);
868+
break;
869+
default:
870+
key_to_s = rb_convert_type(key, T_STRING, "String", "to_s");
871+
break;
869872
}
870-
Check_Type(key_to_s, T_STRING);
873+
871874
generate_json(buffer, Vstate, state, key_to_s);
872875
fbuffer_append(buffer, delim2, delim2_len);
873876
generate_json(buffer, Vstate, state, val);

0 commit comments

Comments
 (0)