Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve performance of Oj.dump with compat/rails mode #675

Merged
merged 1 commit into from Aug 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 9 additions & 9 deletions ext/oj/mimic_json.c
Expand Up @@ -464,19 +464,19 @@ oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
} else {
h = argv[1];
}
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_indent_sym)) {
if (!oj_hash_has_key(h, oj_indent_sym)) {
rb_hash_aset(h, oj_indent_sym, rb_str_new2(" "));
}
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_space_before_sym)) {
if (!oj_hash_has_key(h, oj_space_before_sym)) {
rb_hash_aset(h, oj_space_before_sym, rb_str_new2(""));
}
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_space_sym)) {
if (!oj_hash_has_key(h, oj_space_sym)) {
rb_hash_aset(h, oj_space_sym, rb_str_new2(" "));
}
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_object_nl_sym)) {
if (!oj_hash_has_key(h, oj_object_nl_sym)) {
rb_hash_aset(h, oj_object_nl_sym, rb_str_new2("\n"));
}
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_array_nl_sym)) {
if (!oj_hash_has_key(h, oj_array_nl_sym)) {
rb_hash_aset(h, oj_array_nl_sym, rb_str_new2("\n"));
}
if (Qundef == state_class) {
Expand Down Expand Up @@ -548,31 +548,31 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
pi.options.allow_nan = (Qtrue == v) ? Yes : No;
}

if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_hash_class_sym)) {
if (oj_hash_has_key(ropts, oj_hash_class_sym)) {
if (Qnil == (v = rb_hash_lookup(ropts, oj_hash_class_sym))) {
pi.options.hash_class = Qnil;
} else {
rb_check_type(v, T_CLASS);
pi.options.hash_class = v;
}
}
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_object_class_sym)) {
if (oj_hash_has_key(ropts, oj_object_class_sym)) {
if (Qnil == (v = rb_hash_lookup(ropts, oj_object_class_sym))) {
pi.options.hash_class = Qnil;
} else {
rb_check_type(v, T_CLASS);
pi.options.hash_class = v;
}
}
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_array_class_sym)) {
if (oj_hash_has_key(ropts, oj_array_class_sym)) {
if (Qnil == (v = rb_hash_lookup(ropts, oj_array_class_sym))) {
pi.options.array_class = Qnil;
} else {
rb_check_type(v, T_CLASS);
pi.options.array_class = v;
}
}
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_decimal_class_sym)) {
if (oj_hash_has_key(ropts, oj_decimal_class_sym)) {
pi.options.compat_bigdec = (oj_bigdecimal_class ==
rb_hash_lookup(ropts, oj_decimal_class_sym));
}
Expand Down
34 changes: 20 additions & 14 deletions ext/oj/oj.c
Expand Up @@ -40,7 +40,6 @@ ID oj_error_id;
ID oj_file_id;
ID oj_fileno_id;
ID oj_ftype_id;
ID oj_has_key_id;
ID oj_hash_end_id;
ID oj_hash_key_id;
ID oj_hash_set_id;
Expand Down Expand Up @@ -582,6 +581,14 @@ static VALUE set_def_opts(VALUE self, VALUE opts) {
return Qnil;
}

bool oj_hash_has_key(VALUE hash, VALUE key)
{
if (Qundef == rb_hash_lookup2(hash, key, Qundef)) {
return false;
}
return true;
}

void oj_parse_options(VALUE ropts, Options copts) {
struct _yesNoOpt ynos[] = {{circular_sym, &copts->circular},
{auto_define_sym, &copts->auto_define},
Expand Down Expand Up @@ -612,7 +619,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
if (T_HASH != rb_type(ropts)) {
return;
}
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_indent_sym)) {
if (oj_hash_has_key(ropts, oj_indent_sym)) {
v = rb_hash_lookup(ropts, oj_indent_sym);
switch (rb_type(v)) {
case T_NIL:
Expand Down Expand Up @@ -773,7 +780,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
if (Qnil != (v = rb_hash_lookup(ropts, compat_bigdecimal_sym))) {
copts->compat_bigdec = (Qtrue == v);
}
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_decimal_class_sym)) {
if (oj_hash_has_key(ropts, oj_decimal_class_sym)) {
v = rb_hash_lookup(ropts, oj_decimal_class_sym);
if (rb_cFloat == v) {
copts->compat_bigdec = false;
Expand All @@ -783,7 +790,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
rb_raise(rb_eArgError, ":decimal_class must be BigDecimal or Float.");
}
}
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, create_id_sym)) {
if (oj_hash_has_key(ropts, create_id_sym)) {
v = rb_hash_lookup(ropts, create_id_sym);
if (Qnil == v) {
if (oj_json_class != oj_default_options.create_id && NULL != copts->create_id) {
Expand All @@ -805,7 +812,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
}
}
for (o = ynos; 0 != o->attr; o++) {
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, o->sym)) {
if (oj_hash_has_key(ropts, o->sym)) {
v = rb_hash_lookup(ropts, o->sym);
if (Qnil == v) {
*o->attr = NotSet;
Expand All @@ -820,7 +827,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
}
}
}
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_space_sym)) {
if (oj_hash_has_key(ropts, oj_space_sym)) {
if (Qnil == (v = rb_hash_lookup(ropts, oj_space_sym))) {
copts->dump_opts.after_size = 0;
*copts->dump_opts.after_sep = '\0';
Expand All @@ -835,7 +842,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
copts->dump_opts.after_size = (uint8_t)len;
}
}
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_space_before_sym)) {
if (oj_hash_has_key(ropts, oj_space_before_sym)) {
if (Qnil == (v = rb_hash_lookup(ropts, oj_space_before_sym))) {
copts->dump_opts.before_size = 0;
*copts->dump_opts.before_sep = '\0';
Expand All @@ -850,7 +857,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
copts->dump_opts.before_size = (uint8_t)len;
}
}
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_object_nl_sym)) {
if (oj_hash_has_key(ropts, oj_object_nl_sym)) {
if (Qnil == (v = rb_hash_lookup(ropts, oj_object_nl_sym))) {
copts->dump_opts.hash_size = 0;
*copts->dump_opts.hash_nl = '\0';
Expand All @@ -865,7 +872,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
copts->dump_opts.hash_size = (uint8_t)len;
}
}
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_array_nl_sym)) {
if (oj_hash_has_key(ropts, oj_array_nl_sym)) {
if (Qnil == (v = rb_hash_lookup(ropts, oj_array_nl_sym))) {
copts->dump_opts.array_size = 0;
*copts->dump_opts.array_nl = '\0';
Expand Down Expand Up @@ -914,23 +921,23 @@ void oj_parse_options(VALUE ropts, Options copts) {
} else if (Qfalse == v) {
copts->escape_mode = JSONEsc;
}
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_hash_class_sym)) {
if (oj_hash_has_key(ropts, oj_hash_class_sym)) {
if (Qnil == (v = rb_hash_lookup(ropts, oj_hash_class_sym))) {
copts->hash_class = Qnil;
} else {
rb_check_type(v, T_CLASS);
copts->hash_class = v;
}
}
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_object_class_sym)) {
if (oj_hash_has_key(ropts, oj_object_class_sym)) {
if (Qnil == (v = rb_hash_lookup(ropts, oj_object_class_sym))) {
copts->hash_class = Qnil;
} else {
rb_check_type(v, T_CLASS);
copts->hash_class = v;
}
}
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_array_class_sym)) {
if (oj_hash_has_key(ropts, oj_array_class_sym)) {
if (Qnil == (v = rb_hash_lookup(ropts, oj_array_class_sym))) {
copts->array_class = Qnil;
} else {
Expand All @@ -939,7 +946,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
}
}
oj_parse_opt_match_string(&copts->str_rx, ropts);
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, ignore_sym)) {
if (oj_hash_has_key(ropts, ignore_sym)) {
xfree(copts->ignore);
copts->ignore = NULL;
if (Qnil != (v = rb_hash_lookup(ropts, ignore_sym))) {
Expand Down Expand Up @@ -1785,7 +1792,6 @@ void Init_oj() {
oj_file_id = rb_intern("file?");
oj_fileno_id = rb_intern("fileno");
oj_ftype_id = rb_intern("ftype");
oj_has_key_id = rb_intern("has_key?");
oj_hash_end_id = rb_intern("hash_end");
oj_hash_key_id = rb_intern("hash_key");
oj_hash_set_id = rb_intern("hash_set");
Expand Down
2 changes: 1 addition & 1 deletion ext/oj/oj.h
Expand Up @@ -245,6 +245,7 @@ extern VALUE oj_compat_parse_cstr(int argc, VALUE *argv, char *json, size_t len)
extern VALUE oj_object_parse_cstr(int argc, VALUE *argv, char *json, size_t len);
extern VALUE oj_custom_parse_cstr(int argc, VALUE *argv, char *json, size_t len);

extern bool oj_hash_has_key(VALUE hash, VALUE key);
extern void oj_parse_options(VALUE ropts, Options copts);

extern void oj_dump_obj_to_json(VALUE obj, Options copts, Out out);
Expand Down Expand Up @@ -327,7 +328,6 @@ extern ID oj_exclude_end_id;
extern ID oj_file_id;
extern ID oj_fileno_id;
extern ID oj_ftype_id;
extern ID oj_has_key_id;
extern ID oj_hash_end_id;
extern ID oj_hash_key_id;
extern ID oj_hash_set_id;
Expand Down