Skip to content

Commit 4e221cf

Browse files
authored
Merge pull request #1046 from Watson1978/improve/performance
Improve performance to call Mysql2::Result#each and Mysql2::Result#fields
2 parents c8c346d + a734989 commit 4e221cf

File tree

3 files changed

+29
-19
lines changed

3 files changed

+29
-19
lines changed

ext/mysql2/client.c

+10-7
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ VALUE cMysql2Client;
1818
extern VALUE mMysql2, cMysql2Error, cMysql2TimeoutError;
1919
static VALUE sym_id, sym_version, sym_header_version, sym_async, sym_symbolize_keys, sym_as, sym_array, sym_stream;
2020
static VALUE sym_no_good_index_used, sym_no_index_used, sym_query_was_slow;
21-
static ID intern_brackets, intern_merge, intern_merge_bang, intern_new_with_args;
21+
static ID intern_brackets, intern_merge, intern_merge_bang, intern_new_with_args,
22+
intern_current_query_options, intern_read_timeout;
2223

2324
#define REQUIRE_INITIALIZED(wrapper) \
2425
if (!wrapper->initialized) { \
@@ -579,7 +580,7 @@ static VALUE rb_mysql_client_async_result(VALUE self) {
579580
rb_raise_mysql2_error(wrapper);
580581
}
581582

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

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

642-
read_timeout = rb_iv_get(async_args->self, "@read_timeout");
643+
read_timeout = rb_ivar_get(async_args->self, intern_read_timeout);
643644

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

768769
(void)RB_GC_GUARD(current);
769770
Check_Type(current, T_HASH);
770-
rb_iv_set(self, "@current_query_options", current);
771+
rb_ivar_set(self, intern_current_query_options, current);
771772

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

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

@@ -1471,6 +1472,8 @@ void init_mysql2_client() {
14711472
intern_merge = rb_intern("merge");
14721473
intern_merge_bang = rb_intern("merge!");
14731474
intern_new_with_args = rb_intern("new_with_args");
1475+
intern_current_query_options = rb_intern("@current_query_options");
1476+
intern_read_timeout = rb_intern("@read_timeout");
14741477

14751478
#ifdef CLIENT_LONG_PASSWORD
14761479
rb_const_set(cMysql2Client, rb_intern("LONG_PASSWORD"),

ext/mysql2/result.c

+15-10
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,15 @@ typedef struct {
3030
int streaming;
3131
ID db_timezone;
3232
ID app_timezone;
33-
VALUE block_given;
33+
int block_given; /* boolean */
3434
} result_each_args;
3535

3636
extern VALUE mMysql2, cMysql2Client, cMysql2Error;
3737
static VALUE cMysql2Result, cDateTime, cDate;
3838
static VALUE opt_decimal_zero, opt_float_zero, opt_time_year, opt_time_month, opt_utc_offset;
3939
static ID intern_new, intern_utc, intern_local, intern_localtime, intern_local_offset,
40-
intern_civil, intern_new_offset, intern_merge, intern_BigDecimal;
40+
intern_civil, intern_new_offset, intern_merge, intern_BigDecimal,
41+
intern_query_options;
4142
static VALUE sym_symbolize_keys, sym_as, sym_array, sym_database_timezone,
4243
sym_application_timezone, sym_local, sym_utc, sym_cast_booleans,
4344
sym_cache_rows, sym_cast, sym_stream, sym_name;
@@ -695,7 +696,7 @@ static VALUE rb_mysql_result_fetch_fields(VALUE self) {
695696

696697
GET_RESULT(self);
697698

698-
defaults = rb_iv_get(self, "@query_options");
699+
defaults = rb_ivar_get(self, intern_query_options);
699700
Check_Type(defaults, T_HASH);
700701
if (rb_hash_aref(defaults, sym_symbolize_keys) == Qtrue) {
701702
symbolizeKeys = 1;
@@ -740,7 +741,7 @@ static VALUE rb_mysql_result_each_(VALUE self,
740741
row = fetch_row_func(self, fields, args);
741742
if (row != Qnil) {
742743
wrapper->numberOfRows++;
743-
if (args->block_given != Qnil) {
744+
if (args->block_given) {
744745
rb_yield(row);
745746
}
746747
}
@@ -790,7 +791,7 @@ static VALUE rb_mysql_result_each_(VALUE self,
790791
return Qnil;
791792
}
792793

793-
if (args->block_given != Qnil) {
794+
if (args->block_given) {
794795
rb_yield(row);
795796
}
796797
}
@@ -808,7 +809,7 @@ static VALUE rb_mysql_result_each_(VALUE self,
808809

809810
static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
810811
result_each_args args;
811-
VALUE defaults, opts, block, (*fetch_row_func)(VALUE, MYSQL_FIELD *fields, const result_each_args *args);
812+
VALUE defaults, opts, (*fetch_row_func)(VALUE, MYSQL_FIELD *fields, const result_each_args *args);
812813
ID db_timezone, app_timezone, dbTz, appTz;
813814
int symbolizeKeys, asArray, castBool, cacheRows, cast;
814815

@@ -818,9 +819,12 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
818819
rb_raise(cMysql2Error, "Statement handle already closed");
819820
}
820821

821-
defaults = rb_iv_get(self, "@query_options");
822+
defaults = rb_ivar_get(self, intern_query_options);
822823
Check_Type(defaults, T_HASH);
823-
if (rb_scan_args(argc, argv, "01&", &opts, &block) == 1) {
824+
825+
// A block can be passed to this method, but since we don't call the block directly from C,
826+
// we don't need to capture it into a variable here with the "&" scan arg.
827+
if (rb_scan_args(argc, argv, "01", &opts) == 1) {
824828
opts = rb_funcall(defaults, intern_merge, 1, opts);
825829
} else {
826830
opts = defaults;
@@ -886,7 +890,7 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
886890
args.cast = cast;
887891
args.db_timezone = db_timezone;
888892
args.app_timezone = app_timezone;
889-
args.block_given = block;
893+
args.block_given = rb_block_given_p();
890894

891895
if (wrapper->stmt_wrapper) {
892896
fetch_row_func = rb_mysql_result_fetch_row_stmt;
@@ -951,7 +955,7 @@ VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_
951955
}
952956

953957
rb_obj_call_init(obj, 0, NULL);
954-
rb_iv_set(obj, "@query_options", options);
958+
rb_ivar_set(obj, intern_query_options, options);
955959

956960
/* Options that cannot be changed in results.each(...) { |row| }
957961
* should be processed here. */
@@ -980,6 +984,7 @@ void init_mysql2_result() {
980984
intern_civil = rb_intern("civil");
981985
intern_new_offset = rb_intern("new_offset");
982986
intern_BigDecimal = rb_intern("BigDecimal");
987+
intern_query_options = rb_intern("@query_options");
983988

984989
sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys"));
985990
sym_as = ID2SYM(rb_intern("as"));

ext/mysql2/statement.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
extern VALUE mMysql2, cMysql2Error;
44
static VALUE cMysql2Statement, cBigDecimal, cDateTime, cDate;
55
static VALUE sym_stream, intern_new_with_args, intern_each, intern_to_s, intern_merge_bang;
6-
static VALUE intern_sec_fraction, intern_usec, intern_sec, intern_min, intern_hour, intern_day, intern_month, intern_year;
6+
static VALUE intern_sec_fraction, intern_usec, intern_sec, intern_min, intern_hour, intern_day, intern_month, intern_year,
7+
intern_query_options;
78

89
#define GET_STATEMENT(self) \
910
mysql_stmt_wrapper *stmt_wrapper; \
@@ -404,7 +405,7 @@ static VALUE rb_mysql_stmt_execute(int argc, VALUE *argv, VALUE self) {
404405
}
405406

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

@@ -599,4 +600,5 @@ void init_mysql2_statement() {
599600

600601
intern_to_s = rb_intern("to_s");
601602
intern_merge_bang = rb_intern("merge!");
603+
intern_query_options = rb_intern("@query_options");
602604
}

0 commit comments

Comments
 (0)