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_without_mysql_casting
|
||||
define_bench_task :sequel
|
||||
define_bench_task :allocations
|
||||
end
|
||||
|
||||
# Load custom tasks
|
||||
Dir['tasks/*.rake'].sort.each { |f| load f }
|
||||
|
|
|
@ -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 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;
|
||||
static VALUE intern_encoding_from_charset;
|
||||
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;
|
||||
unsigned int i = 0;
|
||||
unsigned long * fieldLengths;
|
||||
double column_to_double;
|
||||
void * ptr;
|
||||
#ifdef HAVE_RUBY_ENCODING_H
|
||||
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;
|
||||
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);
|
||||
if (column_to_double == 0.000000){
|
||||
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);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MYSQL_TYPE_TIME: { // TIME field
|
||||
int hour, min, sec, tokens;
|
||||
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 (app_timezone == intern_local) {
|
||||
val = rb_funcall(val, intern_localtime, 0);
|
||||
|
@ -435,6 +436,8 @@ void init_mysql2_result() {
|
|||
opt_decimal_zero = rb_str_new2("0.0");
|
||||
rb_global_variable(&opt_float_zero);
|
||||
opt_float_zero = rb_float_new((double)0);
|
||||
opt_time_year = INT2NUM(2000);
|
||||
opt_time_month = INT2NUM(1);
|
||||
|
||||
#ifdef HAVE_RUBY_ENCODING_H
|
||||
binaryEncoding = rb_enc_find("binary");
|
||||
|
|
Loading…
Reference in New Issue