Skip to content

Instantly share code, notes, and snippets.

@funny-falcon
Created March 15, 2011 22:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save funny-falcon/871634 to your computer and use it in GitHub Desktop.
Save funny-falcon/871634 to your computer and use it in GitHub Desktop.
speedup sequel datetime parse
~/tmp/ruby-sequel$ ruby test_sequel_times.rb
user system total real
base 6.870000 0.200000 7.070000 ( 7.534538)
~/tmp/ruby-sequel$ ruby test_sequel_times.rb home_run
user system total real
home_run 5.350000 0.160000 5.510000 ( 5.856684)
~/tmp/ruby-sequel$ ruby test_sequel_times.rb fix
user system total real
fix 2.490000 0.150000 2.640000 ( 2.807951)
class Time
class << self
def relaxed_rfc3339(date)
if /\A\s*
(-?\d+)-(\d\d)-(\d\d)
[T ]
(\d\d):(\d\d):(\d\d)
(?:\.(\d+))?
(Z|[+-]\d\d(?::?\d\d)?)?
\s*\z/ix =~ date
year = $1.to_i
mon = $2.to_i
day = $3.to_i
hour = $4.to_i
min = $5.to_i
sec = $6.to_i
usec = $7 ? "#{$7}000000"[0,6].to_i : 0
if $8
zone = $8
if zone == 'Z'
offset = 0
elsif zone =~ /^([+-])(\d\d):?(\d\d)?$/
offset = ($1 == '+' ? 1 : -1) * ($2.to_i * 3600 + ($3 || 0).to_i * 60)
end
year, mon, day, hour, min, sec =
apply_offset(year, mon, day, hour, min, sec, offset)
t = self.utc(year, mon, day, hour, min, sec, usec)
t.localtime unless zone =~ /Z|-00:?(00)?/
t
else
self.local(year, mon, day, hour, min, sec, usec)
end
end
end
end
end
module Sequel
def self.string_to_datetime(string)
begin
if datetime_class == DateTime
DateTime.parse(string, convert_two_digit_years)
elsif datetime_class.respond_to?(:relaxed_rfc3339)
datetime_class.relaxed_rfc3339(string) || datetime_class.parse(string)
else
datetime_class.parse(string)
end
rescue => e
raise convert_exception_class(e, InvalidValue)
end
end
end
require 'home_run' if ARGV[0] == 'home_run'
require 'rubygems'
require 'sequel'
require 'benchmark'
require './sequel_time_parse' if ARGV[0] == 'fix'
include Benchmark
Sequel.single_threaded = true
DB = Sequel.sqlite
DB.create_table :items do
primary_key :id
String :login
String :name
DateTime :created_at
DateTime :updated_at
end
items = DB[:items]
for i in 1..100
items.insert(:login => "login#{i}", :name => "name#{i}",
:created_at => Time.now - i,
:updated_at => Time.now + i
)
end
class Item < Sequel::Model
end
bm(6) do |x|
x.report(ARGV[0] || 'base') do 100.times { Item.all } end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment