Avoid INT2NUM overhead when coercing date specific elements for MYSQL_TYPE_TIME + introduce basic infrastructure for measuring GC overhead
This commit is contained in:
parent
d9153b82fc
commit
2609783aeb
2
Rakefile
2
Rakefile
@ -47,7 +47,7 @@ namespace :bench do
|
|||||||
define_bench_task :query_with_mysql_casting
|
define_bench_task :query_with_mysql_casting
|
||||||
define_bench_task :query_without_mysql_casting
|
define_bench_task :query_without_mysql_casting
|
||||||
define_bench_task :sequel
|
define_bench_task :sequel
|
||||||
|
define_bench_task :allocations
|
||||||
end
|
end
|
||||||
|
|
||||||
# Load custom tasks
|
# Load custom tasks
|
||||||
Dir['tasks/*.rake'].sort.each { |f| load f }
|
Dir['tasks/*.rake'].sort.each { |f| load f }
|
||||||
|
33
benchmark/allocations.rb
Normal file
33
benchmark/allocations.rb
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
|
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
||||||
|
|
||||||
|
raise Mysql2::Mysql2Error.new("GC allocation benchmarks only supported on Ruby 1.9!") unless RUBY_VERSION =~ /1\.9/
|
||||||
|
|
||||||
|
require 'rubygems'
|
||||||
|
require 'benchmark'
|
||||||
|
require 'active_record'
|
||||||
|
|
||||||
|
ActiveRecord::Base.default_timezone = :local
|
||||||
|
ActiveRecord::Base.time_zone_aware_attributes = true
|
||||||
|
|
||||||
|
class Mysql2Model < ActiveRecord::Base
|
||||||
|
set_table_name :mysql2_test
|
||||||
|
end
|
||||||
|
|
||||||
|
def bench_allocations(feature, iterations = 10, &blk)
|
||||||
|
puts "GC overhead for #{feature}"
|
||||||
|
Mysql2Model.establish_connection(:adapter => 'mysql2', :database => 'test')
|
||||||
|
GC::Profiler.clear
|
||||||
|
GC::Profiler.enable
|
||||||
|
iterations.times{ blk.call }
|
||||||
|
GC::Profiler.report(STDOUT)
|
||||||
|
GC::Profiler.disable
|
||||||
|
end
|
||||||
|
|
||||||
|
bench_allocations('coercion') do
|
||||||
|
Mysql2Model.all(:limit => 1000).each{ |r|
|
||||||
|
r.attributes.keys.each{ |k|
|
||||||
|
r.send(k.to_sym)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
@ -6,7 +6,7 @@ rb_encoding *binaryEncoding;
|
|||||||
|
|
||||||
VALUE cMysql2Result;
|
VALUE cMysql2Result;
|
||||||
VALUE cBigDecimal, cDate, cDateTime;
|
VALUE cBigDecimal, cDate, cDateTime;
|
||||||
VALUE opt_decimal_zero, opt_float_zero;
|
VALUE opt_decimal_zero, opt_float_zero, opt_time_year, opt_time_month;
|
||||||
extern VALUE mMysql2, cMysql2Client, cMysql2Error;
|
extern VALUE mMysql2, cMysql2Client, cMysql2Error;
|
||||||
static VALUE intern_encoding_from_charset;
|
static VALUE intern_encoding_from_charset;
|
||||||
static ID intern_new, intern_utc, intern_local, intern_encoding_from_charset_code,
|
static ID intern_new, intern_utc, intern_local, intern_encoding_from_charset_code,
|
||||||
@ -96,7 +96,6 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
|
|||||||
MYSQL_FIELD * fields = NULL;
|
MYSQL_FIELD * fields = NULL;
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
unsigned long * fieldLengths;
|
unsigned long * fieldLengths;
|
||||||
double column_to_double;
|
|
||||||
void * ptr;
|
void * ptr;
|
||||||
#ifdef HAVE_RUBY_ENCODING_H
|
#ifdef HAVE_RUBY_ENCODING_H
|
||||||
rb_encoding *default_internal_enc = rb_default_internal_encoding();
|
rb_encoding *default_internal_enc = rb_default_internal_encoding();
|
||||||
@ -155,7 +154,8 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_FLOAT: // FLOAT field
|
case MYSQL_TYPE_FLOAT: // FLOAT field
|
||||||
case MYSQL_TYPE_DOUBLE: // DOUBLE or REAL field
|
case MYSQL_TYPE_DOUBLE: { // DOUBLE or REAL field
|
||||||
|
double column_to_double;
|
||||||
column_to_double = strtod(row[i], NULL);
|
column_to_double = strtod(row[i], NULL);
|
||||||
if (column_to_double == 0.000000){
|
if (column_to_double == 0.000000){
|
||||||
val = opt_float_zero;
|
val = opt_float_zero;
|
||||||
@ -163,10 +163,11 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
|
|||||||
val = rb_float_new(column_to_double);
|
val = rb_float_new(column_to_double);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case MYSQL_TYPE_TIME: { // TIME field
|
case MYSQL_TYPE_TIME: { // TIME field
|
||||||
int hour, min, sec, tokens;
|
int hour, min, sec, tokens;
|
||||||
tokens = sscanf(row[i], "%2d:%2d:%2d", &hour, &min, &sec);
|
tokens = sscanf(row[i], "%2d:%2d:%2d", &hour, &min, &sec);
|
||||||
val = rb_funcall(rb_cTime, db_timezone, 6, INT2NUM(2000), INT2NUM(1), INT2NUM(1), INT2NUM(hour), INT2NUM(min), INT2NUM(sec));
|
val = rb_funcall(rb_cTime, db_timezone, 6, opt_time_year, opt_time_month, opt_time_month, INT2NUM(hour), INT2NUM(min), INT2NUM(sec));
|
||||||
if (!NIL_P(app_timezone)) {
|
if (!NIL_P(app_timezone)) {
|
||||||
if (app_timezone == intern_local) {
|
if (app_timezone == intern_local) {
|
||||||
val = rb_funcall(val, intern_localtime, 0);
|
val = rb_funcall(val, intern_localtime, 0);
|
||||||
@ -435,6 +436,8 @@ void init_mysql2_result() {
|
|||||||
opt_decimal_zero = rb_str_new2("0.0");
|
opt_decimal_zero = rb_str_new2("0.0");
|
||||||
rb_global_variable(&opt_float_zero);
|
rb_global_variable(&opt_float_zero);
|
||||||
opt_float_zero = rb_float_new((double)0);
|
opt_float_zero = rb_float_new((double)0);
|
||||||
|
opt_time_year = INT2NUM(2000);
|
||||||
|
opt_time_month = INT2NUM(1);
|
||||||
|
|
||||||
#ifdef HAVE_RUBY_ENCODING_H
|
#ifdef HAVE_RUBY_ENCODING_H
|
||||||
binaryEncoding = rb_enc_find("binary");
|
binaryEncoding = rb_enc_find("binary");
|
||||||
|
Loading…
Reference in New Issue
Block a user