Skip to content

Commit

Permalink
Use rb_ivar_get/rb_ivar_set to improve performance
Browse files Browse the repository at this point in the history
By convert C-string to Ruby string ID each time, it will take a slightly time to call method each time.
This patch will catch the Ruby string ID to cut off the time.

* Before
```
Warming up --------------------------------------
               query   886.000  i/100ms
                each    67.339k i/100ms
              fields   195.612k i/100ms
Calculating -------------------------------------
               query      9.385k (± 4.5%) i/s -     46.958k in   5.016539s
                each    901.633k (± 0.2%) i/s -      4.512M in   5.003951s
              fields      3.779M (± 0.2%) i/s -     18.974M in   5.021533s
```

* After
```
Warming up --------------------------------------
               query   845.000  i/100ms
                each    86.916k i/100ms
              fields   231.527k i/100ms
Calculating -------------------------------------
               query      9.553k (± 2.0%) i/s -     48.320k in   5.059947s
                each      1.133M (± 0.3%) i/s -      5.736M in   5.062606s
              fields      6.319M (± 0.1%) i/s -     31.719M in   5.019960s
```
  • Loading branch information
Watson1978 committed May 17, 2019
1 parent c8c346d commit d479969
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 13 deletions.
17 changes: 10 additions & 7 deletions ext/mysql2/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ VALUE cMysql2Client;
extern VALUE mMysql2, cMysql2Error, cMysql2TimeoutError;
static VALUE sym_id, sym_version, sym_header_version, sym_async, sym_symbolize_keys, sym_as, sym_array, sym_stream;
static VALUE sym_no_good_index_used, sym_no_index_used, sym_query_was_slow;
static ID intern_brackets, intern_merge, intern_merge_bang, intern_new_with_args;
static ID intern_brackets, intern_merge, intern_merge_bang, intern_new_with_args,
intern_current_query_options, intern_read_timeout;

#define REQUIRE_INITIALIZED(wrapper) \
if (!wrapper->initialized) { \
Expand Down Expand Up @@ -579,7 +580,7 @@ static VALUE rb_mysql_client_async_result(VALUE self) {
rb_raise_mysql2_error(wrapper);
}

is_streaming = rb_hash_aref(rb_iv_get(self, "@current_query_options"), sym_stream);
is_streaming = rb_hash_aref(rb_ivar_get(self, intern_current_query_options), sym_stream);
if (is_streaming == Qtrue) {
result = (MYSQL_RES *)rb_thread_call_without_gvl(nogvl_use_result, wrapper, RUBY_UBF_IO, 0);
} else {
Expand All @@ -596,7 +597,7 @@ static VALUE rb_mysql_client_async_result(VALUE self) {
}

// Duplicate the options hash and put the copy in the Result object
current = rb_hash_dup(rb_iv_get(self, "@current_query_options"));
current = rb_hash_dup(rb_ivar_get(self, intern_current_query_options));
(void)RB_GC_GUARD(current);
Check_Type(current, T_HASH);
resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result, Qnil);
Expand Down Expand Up @@ -639,7 +640,7 @@ static VALUE do_query(void *args) {
int retval;
VALUE read_timeout;

read_timeout = rb_iv_get(async_args->self, "@read_timeout");
read_timeout = rb_ivar_get(async_args->self, intern_read_timeout);

tvp = NULL;
if (!NIL_P(read_timeout)) {
Expand Down Expand Up @@ -767,7 +768,7 @@ static VALUE rb_mysql_query(VALUE self, VALUE sql, VALUE current) {

(void)RB_GC_GUARD(current);
Check_Type(current, T_HASH);
rb_iv_set(self, "@current_query_options", current);
rb_ivar_set(self, intern_current_query_options, current);

Check_Type(sql, T_STRING);
/* ensure the string is in the encoding the connection is expecting */
Expand Down Expand Up @@ -1179,7 +1180,7 @@ static VALUE rb_mysql_client_store_result(VALUE self)
}

// Duplicate the options hash and put the copy in the Result object
current = rb_hash_dup(rb_iv_get(self, "@current_query_options"));
current = rb_hash_dup(rb_ivar_get(self, intern_current_query_options));
(void)RB_GC_GUARD(current);
Check_Type(current, T_HASH);
resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result, Qnil);
Expand Down Expand Up @@ -1265,7 +1266,7 @@ static VALUE set_read_timeout(VALUE self, VALUE value) {
/* Set the instance variable here even though _mysql_client_options
might not succeed, because the timeout is used in other ways
elsewhere */
rb_iv_set(self, "@read_timeout", value);
rb_ivar_set(self, intern_read_timeout, value);
return _mysql_client_options(self, MYSQL_OPT_READ_TIMEOUT, value);
}

Expand Down Expand Up @@ -1471,6 +1472,8 @@ void init_mysql2_client() {
intern_merge = rb_intern("merge");
intern_merge_bang = rb_intern("merge!");
intern_new_with_args = rb_intern("new_with_args");
intern_current_query_options = rb_intern("@current_query_options");
intern_read_timeout = rb_intern("@read_timeout");

#ifdef CLIENT_LONG_PASSWORD
rb_const_set(cMysql2Client, rb_intern("LONG_PASSWORD"),
Expand Down
10 changes: 6 additions & 4 deletions ext/mysql2/result.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ extern VALUE mMysql2, cMysql2Client, cMysql2Error;
static VALUE cMysql2Result, cDateTime, cDate;
static VALUE opt_decimal_zero, opt_float_zero, opt_time_year, opt_time_month, opt_utc_offset;
static ID intern_new, intern_utc, intern_local, intern_localtime, intern_local_offset,
intern_civil, intern_new_offset, intern_merge, intern_BigDecimal;
intern_civil, intern_new_offset, intern_merge, intern_BigDecimal,
intern_query_options;
static VALUE sym_symbolize_keys, sym_as, sym_array, sym_database_timezone,
sym_application_timezone, sym_local, sym_utc, sym_cast_booleans,
sym_cache_rows, sym_cast, sym_stream, sym_name;
Expand Down Expand Up @@ -695,7 +696,7 @@ static VALUE rb_mysql_result_fetch_fields(VALUE self) {

GET_RESULT(self);

defaults = rb_iv_get(self, "@query_options");
defaults = rb_ivar_get(self, intern_query_options);
Check_Type(defaults, T_HASH);
if (rb_hash_aref(defaults, sym_symbolize_keys) == Qtrue) {
symbolizeKeys = 1;
Expand Down Expand Up @@ -818,7 +819,7 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
rb_raise(cMysql2Error, "Statement handle already closed");
}

defaults = rb_iv_get(self, "@query_options");
defaults = rb_ivar_get(self, intern_query_options);
Check_Type(defaults, T_HASH);
if (rb_scan_args(argc, argv, "01&", &opts, &block) == 1) {
opts = rb_funcall(defaults, intern_merge, 1, opts);
Expand Down Expand Up @@ -951,7 +952,7 @@ VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_
}

rb_obj_call_init(obj, 0, NULL);
rb_iv_set(obj, "@query_options", options);
rb_ivar_set(obj, intern_query_options, options);

/* Options that cannot be changed in results.each(...) { |row| }
* should be processed here. */
Expand Down Expand Up @@ -980,6 +981,7 @@ void init_mysql2_result() {
intern_civil = rb_intern("civil");
intern_new_offset = rb_intern("new_offset");
intern_BigDecimal = rb_intern("BigDecimal");
intern_query_options = rb_intern("@query_options");

sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys"));
sym_as = ID2SYM(rb_intern("as"));
Expand Down
6 changes: 4 additions & 2 deletions ext/mysql2/statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
extern VALUE mMysql2, cMysql2Error;
static VALUE cMysql2Statement, cBigDecimal, cDateTime, cDate;
static VALUE sym_stream, intern_new_with_args, intern_each, intern_to_s, intern_merge_bang;
static VALUE intern_sec_fraction, intern_usec, intern_sec, intern_min, intern_hour, intern_day, intern_month, intern_year;
static VALUE intern_sec_fraction, intern_usec, intern_sec, intern_min, intern_hour, intern_day, intern_month, intern_year,
intern_query_options;

#define GET_STATEMENT(self) \
mysql_stmt_wrapper *stmt_wrapper; \
Expand Down Expand Up @@ -404,7 +405,7 @@ static VALUE rb_mysql_stmt_execute(int argc, VALUE *argv, VALUE self) {
}

// Duplicate the options hash, merge! extra opts, put the copy into the Result object
current = rb_hash_dup(rb_iv_get(stmt_wrapper->client, "@query_options"));
current = rb_hash_dup(rb_ivar_get(stmt_wrapper->client, intern_query_options));
(void)RB_GC_GUARD(current);
Check_Type(current, T_HASH);

Expand Down Expand Up @@ -599,4 +600,5 @@ void init_mysql2_statement() {

intern_to_s = rb_intern("to_s");
intern_merge_bang = rb_intern("merge!");
intern_query_options = rb_intern("@query_options");
}

0 comments on commit d479969

Please sign in to comment.